I have one data source like -4,-3,-3,-2,-1,0,1,2,2,3,4 , I have one function and this function can capture repeated number for example in this data source we have -3,2 are repeated .The repeated numbers are reported in end of the program.
I couldn't find good example(I spent 3 hours).
How can I implement a unit test with NUnit that can be test the same situation and it tells me the results, if you have some example , It will be very useful to me.(Really appreciated).
You can use TestCase attributes for simple data like what you've described.
[Test]
[TestCase(new[] { -4, -3, -3, -2, -1, 0, 1, 2, 2, 3, 4 }, new []{-3,2})]
public void YourTest(int[] given, int[] expected)
{ ... }
Note: ReSharper (at least my version of it) doesn't honor multiple test cases like this one so I had to confirm multiple test cases with the NUnit GUI.
First things first - get a working test. Something like this:
[Test]
public void DetectsMinusThreeAndTwo()
{
RepeatingDigitsDetector target = new RepeatingDigitsDetector();
int[] source = new int[] { -4, -3, -3, -2, -1, 0, 1, 2, 2, 3, 4 };
int[] expected = new int[] { -3, -2 };
int[] actual = target.GetRepeats(source);
Assert.AreEqual(expected.Length, actual.Length, "checking lengths");
for (int i = 0; i < expected.Length; i++)
{
Assert.AreEqual(expected[i], actual[i], "checking element {0}", i);
}
}
Later, you can start adding in goodies like the TestCase or TestCaseSource attributes. But if you're trying to do TDD (as the tdd tag implies), you need to start with a test.
I would recommend TestCaseSource in this instance. Several tests could make the data harder to read inside the TestCase attribute.
As your test data gets complex, it will be difficult to handle.
Consider storing your data in another source such as excel, json or Database.
I personally like storing test data in embedded json files.
The package JsonSectionReader provides good support for this.
Related
Is there any way to fast-copy an array to a member of another structure array without using a for loop? I want to print out "6" when I run this code.
using System;
public class Program
{
struct output
{
public int A;
public int B;
}
public static void Main()
{
var output_array = new output[10];
var a_array = new int[] { 0, 2, 4, 6 ,8, 10, 12, 14, 16, 18};
var b_array = new int[] { 1, 3, 5, 7 ,9, 11, 13, 15, 17, 19};
// Copy a_array to output[].A
// and copy b_array_to output[].B , without using any loop.
Console.WriteLine(output_array[3].A);
}
}
It's not going to be specifically fast but it is succinct to use the Zip extension method:
var a_array = new int[] { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 };
var b_array = new int[] { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19 };
var output_array = a_array.Zip(b_array, (a, b) => new output { A = a, B = b }).ToArray();
This obviously creates the array, rather than populating an existing array. That shouldn't be an issue for situations like your example, but maybe it is in some real-world situations. In that case, you could create an array and then Array.Copy the elements over.
EDIT:
Actually, I wonder whether I might have misinterpreted your requirement, in which case creating a new array might be an issue. You have included b_array in your code but a more careful reading of your question and your code seems to suggest that that is irrelevant. Please take care to include ONLY what is relevant to the issue because anything else can cloud the issue and waste everyone's time.
If you specifically want the contents of a_array copied into an existing array and b_array is irrelevant then you can't really do it without a loop but, again, LINQ can help flatten that loop:
var output_array = new output[10];
var a_array = new int[] { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 };
Array.ForEach(Enumerable.Range(0, Math.Min(output_array.Length, a_array.Length)).ToArray(),
i => output_array[i].A = a_array[i]);
I've included that Math.Min call to allow for the two arrays to be different lengths but, if you know they're not, you can do away with that and just use one array. Obviously that ForEach call is masking a loop but the actual you see is more succinct. For a one-line loop though, is it really worth the effort and the fact that you have to generate a int array to do it?
I should also point that, while this looks like it would be a problem with value types:
output_array[i].A = a_array[i]
it actually doesn't. Indexing arrays actually provides direct access to the element, rather than creating a copy, so setting a property of that element is not a problem, even for value types.
The memory layout of a_array and output_array will be different so you can't use any tricks with memory copying the bytes.
There are ways to achieve the copy without using an assign in a for loop, e,g.
for (var i = 0; i < 10; i++)
{
output_array[i].A = a_array[i];
// output_array[i].B = b_array[i];
}
but I doubt anything is going to be faster than that. Of course, I haven't tested and benchmarked it.
Perhaps a better solution is not to copy the bytes at all.
As said in this previous question, I am using the Reactive library in a C# project to group incoming data according to pre-configured policies. All these data implement the following interface:
public interface IPoint
{
object Value { get; }
DateTimeOffset Timestamp { get; }
}
My goal is to implement a "hopping" buffer based on the Timestamps of the received data (both buffer size and hop/shift size are declared at the beginning as TimeSpans). Hop/shift size can be less than the buffer size, which means that some IPoint instances can belong to more than one group.
An example: considering the following IPoint
Value: 1, Timestamp: "2021-05-25T00:00:01"
Value: 2, Timestamp: "2021-05-25T00:00:02"
Value: 3, Timestamp: "2021-05-25T00:00:03"
Value: 4, Timestamp: "2021-05-25T00:00:04"
Value: 5, Timestamp: "2021-05-25T00:00:05"
with a buffer size of 3 seconds and a hop/shift size of 2 seconds, I am expecting them to be grouped as [1, 2, 3], [3, 4, 5].
with a buffer size of 2 seconds and a hop/shift size of 3 seconds, I am expecting them to be grouped as [1, 2], [4, 5]
I've seen that there is a Buffer(timeSpan, timeShift) extension doing this job, but it considers a runtime-calculated timestamp instead of the ones of the passed IPoints.
I've tried to look for a solution, but I couldn't find anything helpful.
I am a newbie at Reactive, so any helpful comment is welcome (also for the other question). Thank you.
Edit: as in the previous question, I am using an ISubject<IPoint> in this way:
ISubject<IPoint> subject = new Subject<IPoint>();
// ...
// when new data come from an external source
public void Add(IPoint newPoint)
{
subject.OnNext(newPoint);
}
// subscription made by another class in order to be called when "hopping" buffer is ready
public void Subscribe(Action<IEnumerable<IPoint>> callback)
{
// TODO: implement buffer + .Subscribe(callback)
}
Or should I say, skip the first element and come back to it at the end.
e.g. say I have
int[] arr = { 2, 4, 3, 9, 1, 0 };
and want to iterate through it like
{ 4, 3, 9, 1, 0, 2 }
I know one way would be like
foreach(int i in arr.Skip(1).Append(new int[] { arr.First() }))
which is why I'm asking whether there's a better looking and/or more efficient way.
Only slightly cleaner than what you've got:
foreach(int i in arr.Skip(1).Concat(arr.Take(1)))
{
...
}
Another way. (not cleaner tho)
Enumerable.Range(1, arr.Length)
.Select(x => arr[x%arr.Length]);
I would hold it into a new collection, like a list, since it will be more ckear what I am doing when somebody else will read my code (if ever). A list is well optimized for this kind of behavior:
var list = arr.ToList();
list.Add(list.ElemntAt(0));
list.RemoveAt(0);
Then you can iterate the list, and it is more verbose to do it this way rather than using a Linq query, which can solve this problem, but it may not be so easy to read.
Why it's not equal? It's the same with CollectionAssert too.
var a = new[] { new[] { 1, 2 }, new[] { 3, 4 } };
var b = new[] { new[] { 1, 2 }, new[] { 3, 4 } };
// if you comment these two lines the test passes
a[0] = a[1];
b[0] = b[1];
Assert.That(a, Is.EqualTo(b));
Gives:
Expected and actual are both <System.Int32[2][]>
Values differ at index [1]
Expected and actual are both <System.Int32[2]>
I'm using nunit 2.6.4.14350 and run from ReSharper test runner in VS .NET 4.5 project.
The same is reproducable for standalone NUnit test runner (2.6.4).
I reported this bug but it's closed as won't fix: https://github.com/nunit/nunit/issues/1209
So you can either use NUnit 3.x or accept that it's just broken in NUnit 2.6.x.
Althoug either a and bare of type Int32[2][] that does not mean they are equal as Equals returns true if the references of your arrays are identical which they are not. What you want is to echeck if their content is the same using a.SequenceEquals(b).
I'm developing a programme to manipulate costs history and eventually a prediction.
The problem I've faced is that I want to calculate modifiers which will be use on the costs history to remove season variance. I need two diffent ways to calculate them and those two are nearly the same except places where it will be a multiplication instead of an addition.
An example would be :
private void CalculAndSumEveryPeriodeModifier()
{
List<double> averages = MovingAverage.Averages;
for (int i = 0; i < averages.Count; ++i)
{
averages[i] = costsList[i + NbPeriode / 2] / averages[i] // Division changed to substraction
modifiers[((i + NbPeriode / 2) % NbPeriode)] += averages[i];
}
}
I've made an attempt with an abstract class having a private abstract method that takes two doubles. The concrete classes can then implement this method to divide or subtract the doubles at certain points in the algorithm.
The problem with this approach is that I don't know how to unit test it. Can I test the abstract class with the moq framework if yes how? Else I need to test both concrete class which will duplicate code since the tests will be the same.
Is there a way to unit test my attempt or is there a better approach?
Kevin
Why not factor out the common code of the two unit test methods into a shared method?
private int[] input = new int[] { 2, 8, 6, 1, 5, 1, 7, 5, 2, 4 };
[TestMethod]
public void TestVariantA()
{
var obj = new ConcreteA();
DoTest(obj, input, new int[] { -2.8, 3, 1.4, -3.2, 1 });
}
[TestMethod]
public void TestVariantB()
{
var obj = new ConcreteB();
DoTest(obj, input, new int[] { 0.2632, 1.7500, 1.3397, 0.2381, 1.2500 });
}
private void DoTest(AbstractType obj, int input, int expected)
{
...
}