In my company code base we have a bunch of extension method for IEnumerable object.
Some of this method enumerate multiple time the parameter given in entry.
Of course, we don't want the so I'm going to fix those methods.
But first I would like to write some unit test to detect the multiple enumeration.
I come to an implementation of IEnumerable that provide enumeration count information :
public class TestableEnumerable<T> : IEnumerable<T>
{
readonly T[] values;
public TestableEnumerable(T[] values)
{
this.values = values;
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public IEnumerator<T> GetEnumerator()
{
EnumerationCount++;
foreach (var value in values)
{
yield return value;
}
}
public int EnumerationCount { get; private set; }
}
The test look like this:
[TestFixture]
public class EnumerableExtensionsTests
{
TestableEnumerable<int> sut;
[SetUp]
public void SetUp()
{
sut = new TestableEnumerable<int>(new[] { -10, 0, 10 });
}
[Test]
public void Append_Enumerate_Once()
{
var result = sut.Append(1).ToArray();
Assert.That(sut.EnumerationCount, Is.EqualTo(1));
}
}
Does NUnit provide any mechanism to accomplish this more lightly ?
If you looks only for GetEnumerator method calls count, you can use any mock framework to create fake enumerable. There is NUnit.Mock framework. But now it's no longer being developed and NUnit project uses NSubstitute.
var fakeEnumerable = Substitute.For<IEnumerable<int>>();
fakeEnumerable.GetEnumerator().Returns(Substitute.For<IEnumerator<int>>());
fakeEnumerable.ToArray();
fakeEnumerable.ToArray();
fakeEnumerable.Received(2).GetEnumerator();
Also there is another way to enumerate collection twice. It can be done by using IEnumerator.Reset metod.
So it may worth to check Reset method calls too.
Related
I have looked at a number of questions here on this subject but none seem to address the issue I'm having.
I've got code that looks a bit like this...
IBaseDataCollector<MyClass> myDataCollector;
myDataCollector = new Mock<IBaseDataCollector<MyClass>>();
systemUnderTest = new Thing(myDataCollector.Object);
And in my Thing class...
var collection = myDataCollector.SomeMethod()
.SomeSecondMethod()
.GetData();
where both SomeMethod() and SomeSecondMethod() return this (ie the instance of myDataCollector)
When I run my test I get a NullReferenceException on the like where I call myDataCollector.
I tried adding this in my test setup...
myDataCollector.Setup(_=> _.SomeMethod()),Returns(myDataCollector.Object);
but that wouldn't even compile, complaining that it "Could not resolve method 'Returns(IBaseDataCollector)'"
Now, if I refactor my Thing class to read...
myDataCollector.SomeMethod();
myDataCollector.SomeSecondMethod()
var collection = myDataCollector.GetData();
my test executes properly.
If this was it, I'd just refactor my code and get on with life, but, in reality, I need to call my code inside a SelectMany call...
var collection = list.SelectMany(_=> myDataCollector.SomeMethod()
.SomeSecondMethod(_)
.GetData());
Again, I know I could replace the SelectMany with, say, a ForEach and manually populate the collection with the results of each iteration of the call to GetData() so that I can get rid of the fluent element of the calls, but this means refactoring the code just to make the tests work, which feels wrong.
How should I be calling Setup() on my Mocked objects to make my fluent calls work?
Take a look at the following test code (I've invented some details to fill in the blanks). The mocked object instance should be available as a value to return from its own methods as shown.
public class UnitTestExample
{
[Fact]
public void UnitTestExample1()
{
var myClassInterfaceMock = new Mock<IInterface<MyClass>>();
var instance = myClassInterfaceMock.Object;
var myList = new List<MyClass>()
{
new MyClass() { Attribute = 1 }
};
myClassInterfaceMock.Setup(_ => _.SomeMethod()).Returns(instance);
myClassInterfaceMock.Setup(_ => _.SomeSecondMethod()).Returns(instance);
myClassInterfaceMock.Setup(_ => _.GetData()).Returns(myList);
var myDependentClass = new MyDependentClass(instance);
var result = myDependentClass.DoTheThing();
Assert.True(result.Count.Equals(1));
}
}
public interface IInterface<T>
{
IInterface<T> SomeMethod();
IInterface<T> SomeSecondMethod();
List<T> GetData();
}
public class MyClass
{
public int Attribute { get; set; }
}
public class MyDependentClass
{
private readonly IInterface<MyClass> _test;
public MyDependentClass(IInterface<MyClass> test)
{
_test = test;
}
public List<MyClass> DoTheThing()
{
return _test.SomeMethod().SomeSecondMethod().GetData();
}
}
I have written the xUnit test cases in C#. That test class contains so many methods. I need to run the whole test cases in a sequence. How can I set the test case sequence in xUnit?
In xUnit 2.* this can be achieved using the TestCaseOrderer attribute to designate an ordering strategy, which can be used to reference an attribute that is annotated on each test to denote an order.
For example:
Ordering Strategy
[assembly: CollectionBehavior(DisableTestParallelization = true)]
public class PriorityOrderer : ITestCaseOrderer
{
public IEnumerable<TTestCase> OrderTestCases<TTestCase>(IEnumerable<TTestCase> testCases) where TTestCase : ITestCase
{
var sortedMethods = new SortedDictionary<int, List<TTestCase>>();
foreach (TTestCase testCase in testCases)
{
int priority = 0;
foreach (IAttributeInfo attr in testCase.TestMethod.Method.GetCustomAttributes((typeof(TestPriorityAttribute).AssemblyQualifiedName)))
priority = attr.GetNamedArgument<int>("Priority");
GetOrCreate(sortedMethods, priority).Add(testCase);
}
foreach (var list in sortedMethods.Keys.Select(priority => sortedMethods[priority]))
{
list.Sort((x, y) => StringComparer.OrdinalIgnoreCase.Compare(x.TestMethod.Method.Name, y.TestMethod.Method.Name));
foreach (TTestCase testCase in list)
yield return testCase;
}
}
static TValue GetOrCreate<TKey, TValue>(IDictionary<TKey, TValue> dictionary, TKey key) where TValue : new()
{
TValue result;
if (dictionary.TryGetValue(key, out result)) return result;
result = new TValue();
dictionary[key] = result;
return result;
}
}
Attribute
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class TestPriorityAttribute : Attribute
{
public TestPriorityAttribute(int priority)
{
Priority = priority;
}
public int Priority { get; private set; }
}
Test Cases
[TestCaseOrderer("FullNameOfOrderStrategyHere", "OrderStrategyAssemblyName")]
public class PriorityOrderExamples
{
[Fact, TestPriority(5)]
public void Test3()
{
// called third
}
[Fact, TestPriority(0)]
public void Test2()
{
// called second
}
[Fact, TestPriority(-5)]
public void Test1()
{
// called first
}
}
xUnit 2.* ordering samples here
Testpriority: at the bottom of this page.
[PrioritizedFixture]
public class MyTests
{
[Fact, TestPriority(1)]
public void FirstTest()
{
// Test code here is always run first
}
[Fact, TestPriority(2)]
public void SeccondTest()
{
// Test code here is run second
}
}
BTW, I have the same problem right now. And yes, it is not the clean art.. but QA wanted a manual test.. so an automated test with a specific order already is a big leap for them.. (cough) and yes, it is not really unit testing..
If you really have the need to prioritize your tests (probably not your unit tests) you can use Xunit.Priority.
I have used it for some integration testing and works really well and simple without the overhead of having to write your prioritization classes, for simple case scenarios
For some reason, XUnit.Priority didn't work for me. In my test cases, it wasn't running the tests in the priority order specified.
So I tried XUnitPriorityOrderer, which is similar to use but was working (To quickly test it, save the following code in a text editor as OrderedXUnitTests.linq, then open it with LinqPad 6 and execute it. Alternatively, you can also copy the TestClass to Visual Studio and add XUnit, XUnit.Runner.VisualStudio and XUnitPriorityOrderer):
<Query Kind="Program">
<NuGetReference>XUnitPriorityOrderer</NuGetReference>
<Namespace>Xunit</Namespace>
<Namespace>XUnitPriorityOrderer</Namespace>
</Query>
#load "xunit"
// using XUnitPriorityOrderer
// see: https://github.com/frederic-prusse/XUnitPriorityOrderer
void Main()
{
RunTests(); // Call RunTests() or press Alt+Shift+T to initiate testing.
}
#region private::Tests
[TestCaseOrderer(CasePriorityOrderer.TypeName, CasePriorityOrderer.AssembyName)]
public class TestClass
{
static List<string> Order { get; set; }
public TestClass()
{
Order = Order ?? new List<string>();
}
[Fact, Order(2)]
void Test_Xunit_AnotherTest()
{
Order.Add("Test_Xunit_AnotherTest");
Assert.True(3 + 1 == 4);
}
[Fact, Order(1)]
void Test_Xunit()
{
Order.Add("Test_XUnit");
Assert.True(1 + 1 == 2);
}
[Fact, Order(99)]
void Print_Order()
{
Order.Add("Print_Order");
var strOrder = string.Join(", ", Order.ToArray());
strOrder.Dump("Execution Order");
Assert.True(true);
}
}
#endregion
This will run the tests in given order (Order(1), Order(2) and then Order(99)) and will dump the executed tests finally (test method Print_Order()).
You can't, by design. It's deliberately random in order to prevent anyone getting one of those either by desire or by accident.
The randomness is only for a given Test class, so you may be able to achieve your goals by wrapping items you want to control the order of inside a nested class - but in that case, you'll still end up with random order whenever you have more than two Test Methods in a class.
If you're trying to manage the building up of fixtures or context, the built-in IUseFixture<T> mechanism may be appropriate. See the xUnit Cheat Sheet for examples.
But you really need to tell us more about what you're trying to do or we'll just have to get speculative.
I am writing a testing framework for my system, which allows users to create mocked inputs to the system. The system manipulates that input, and updates some of its members for later post processing.
In order to allow users to mock the input, I need to be able to update a mocked input's members. Furthermore, the input may not be a mock, so I would prefer a solution oblivious to the type of element received.
Simply put, I have a function which receives an object and attempts to set one of its properties:
func(object a)
a.m = 5;
Which I want to test by mocking its input a, using the Moq library. Unfortunately, my test failed, since mocked objects' members need to be set using Mock.SetUpGet, instead of standard member assignment.
What would be a good way to test such a function, without changing it?
In order to be able to mock and test it, the property must be virtual, but if that's the case you can use the SetupSet method, rather than SetupGet:
public class A
{
public virtual int m { get; set; }
}
[TestFixture]
public class Tests
{
public static void SetProperty(A a)
{
a.m = 5;
}
[Test]
public void IsThePropertySet()
{
var x = new Mock<A>();
x.SetupSet<int>(a => a.m = 5).Verifiable();
SetProperty(x.Object);
x.Verify();
}
}
Your function should have getters and setters anyway.
And a good way of testing whether your functions work is to do a small-scale test. Initialize an object and send that in to your method, seeing whether it does what you want.
public class myClass
{
public int number;
public void setNumber(int nNum)
{
number = nNum;
}
public int getNumber()
{
return number;
}
}
class Program
{
static void myMethod(myClass obj, int nNumb)
{
//obj.setNumber(nNumb);
obj.number = nNumb;
}
static void Main(string[] args)
{
myClass myObj = new myClass();
myMethod(myObj, 3);
//Console.WriteLine(myObj.getNumber());
Console.WriteLine(myObj.number);
Console.ReadLine();
}
}
}
Output: 3
I'm planning to store all test cases in a excel file with columns indicate test method names, parameters and expected results; however, I found TestCaseSource simply assigns all test cases to every test method. I'm wondering that is there any way I can make NUnit select test cases for methods base on method names I put in the spreadsheet?
Thanks.
There is a way to do this.
For example, as you mentioned, you can create a custom attribute.
The idea is to pass name of test to TestCaseSource.
You can do it by creating TestCaseSource as separate class.
First, TestCaseSource class:
public class SpreadSheetTestCaseSource
{
[ThreadStatic]
public static string TestName = String.Empty;
public static IEnumerable TestCases
{
get
{
SpreadSheetTestCaseProvider.GetTestCases()
.Where(testCase => testCase.TestName == TestName);
}
}
}
Then attribute:
public class MyTestCaseSourceAttribute : TestCaseSourceAttribute
{
public MyTestCaseSourceAttribute(Type sourceType, string sourceName,
[CallerMemberName] string name = null)
: base(sourceType, sourceName)
{
SpreadSheetTestCaseSource.TestName = name;
}
//Another two members impl.
}
And test:
[TestFixture]
public class TestClass
{
[MyTestCaseSource(typeof(SpreadSheetTestCaseSource), "TestCases")]
public void TestMethod()
{
//Test logic
}
}
SpeadSheetTestCaseSource.TestName is thread static. So you can run tests parallel.
This isn't a feature that NUnit supports directly. The various TestCaseSource type attributes have no ability to feed a test method based on the input.
An option would be to create a TestCaseSource for each of your test methods. Each of these would be a simple wrapper that passes in the method name to a single internal method. That internal method would read in the Excel file and only return the rows for the given method name.
PseudoCode;
[TestCaseSource(nameof(TestMethodOneSource))]
public void TestMethodOne(int x, int y, int expected)
{
Assert.That(x + y, Is.EqualTo(expected));
}
public static IEnumerable<object[]> TestMethodOneSource() =>
ReadExcel(nameof(TestMethodOne));
private static IEnumerable<object[]> ReadExcel(string method)
{
// Open and start reading Excel
for(var row in rows)
{
if(row[0] == method)
{
// Return objects minus the method
yield return new [] {row[1], ..., row[n]};
}
}
}
I have a set of tests which are verifying a contract with an external API. I want the test class to implement the contract interface so that if it is ever changed the test class itself enforces that tests are written for any new methods.
So something like
public interface IExternalThing {
Dictionary<string, int> GetSomeValues(int id);
}
[TestFixture]
public class ContractVerification : IExternalThing {
private realExternalThing = new ExternalThing();
private static IEnumerable GetValuesSource {
get
{
yield return new TestCaseData(0).Returns(
new Dictionary<string, int> {
{"thing", 1}
}
);
}
}
[Test]
[TestCaseSource("GetValuesSource")]
public Dictionary<string, int> GetSomeValues(int id) {
return realExternalThing.GetSomeValues(id);
}
}
This approach has worked so far but as this method returns a Dictionary NUnit is reporting failure with the message:
> Expected and actual are both
> <System.Collections.Generic.Dictionary`2[System.String,System.Int32]>
> with 1 elements
I suppose I could approach this another way but if I could just ask NUnit to test Is.EquivalentTo instead of simple equality that would be fantastic.
Is that possible?
http://www.nunit.org/index.php?p=collectionAssert&r=2.5 - CollectionAssert.AreEquivalent()