Recursive class fixtures in C# xUnit - c#

I want to do something like this to provide methods from test classes to other test classes using composition.
public class SomeTestClass : IClassFixture<SomeService>
{
private readonly SomeService SomeService;
public SomeTestClass(SomeService someService)
{
SomeService = someService;
}
[Fact]
private void Test()
{
//....
}
public SomeData CreateSomeData()
{
// populate fields with something based on internal/service state
return new SomeData();
}
public void DoSomeAction(....)
{
// does action which modifies internal/service state
}
}
public class SomeConsumingClass : IClassFixture<SomeTestClass>
{
private readonly SomeTestClass SomeTestClass;
public SomeConsumingClass(SomeTestClass someTestClass)
{
SomeTestClass = someTestClass;
}
[Fact]
private void Test()
{
var data = SomeTestClass.CreateSomeData();
// ....
SomeTestClass.DoSomeAction(...)
}
}
The test in SomeTestClass passes but the test in SomeConsumingClass fails with a message
Class fixture type 'Requirements.SomeTestClass' had one or more unresolved constructor arguments: SomeService someService) (The following constructor parameters did not have matching fixture data: SomeTestClass someTestClass
It seems like a feature like this is not directly supported as it seems to be looking for a parameterless constructor. I intended to use this pattern for each test class, therefore I am looking for some good way to do something similar without too much boilerplate code. Any suggestions on how I could provide methods from the other test classes without inheritance?
EDIT:
Added some additional examples how I imagine myself using this

From the xUnit documentation on Class Fixtures (emphasis added):
Note that you cannot control the order that fixture objects are created, and fixtures cannot take dependencies on other fixtures. If you have need to control creation order and/or have dependencies between fixtures, you should create a class which encapsulates the other two fixtures, so that it can do the object creation itself.
One solution would be to move the CreateSomeData method to SomeService, and then change SomeConsumingClass so that it also implements IClassFixture<SomeService>.
However, it's worth pointing out this line from the documentation regarding when IClassFixture is appropriate:
When to use: when you want to create a single test context and share it among all the tests in the class, and have it cleaned up after all the tests in the class have finished.
From the description you've provided, it doesn't seem clear to me that IClassFixture is necessary here, since all you really want is the ability to call CreateSomeData from different test classes. A dead-simple alternative would be to just move GetSomeData to a utility class that can be directly called from any test fixture that needs it.

So I played around with possible solutions and was able to come up with a solution which allows for identical behavior
public class SomeTestClass
{
private readonly SomeService SomeService;
public SomeTestClass(SomeService someService)
{
SomeService = someService;
}
[Fact]
private void Test()
{
//....
}
public SomeData CreateSomeData()
{
// populate fields with something based on internal/service state
return new SomeData();
}
public void DoSomeAction(....)
{
// does action which modifies internal/service state
}
}
public class SomeDerivingTestClass : SomeTestClass
{
public SomeDerivingTestClass() : base(CreateSomeService())
{
}
private static SomeService CreateSomeService()
{
return new SomeService();
}
}
public class SomeConsumingClass : IClassFixture<SomeDerivingTestClass>
{
private readonly SomeTestClass SomeTestClass;
public SomeConsumingClass(SomeDerivingTestClass someTestClass)
{
SomeTestClass = someTestClass;
}
[Fact]
private void Test()
{
var data = SomeTestClass.CreateSomeData();
// ....
SomeTestClass.DoSomeAction(...)
}
}

Related

How to share one fixture among all test classes?

I want to share DBfixture in all tests. This is the collection created for this purpose:
[CollectionDefinition("db")]
public class TestColDefinition : IClassFixture<DBfixture> { }
I have a base class from which i derive my test classes:
public class TestBase
{
protected readonly ITestOutputHelper testOutputHelper;
protected DBfixture dbf;
public TestBase(ITestOutputHelper testOutputHelper, DBfixture dbf)
{
this.testOutputHelper = testOutputHelper;
this.dbf = dbf;
}
}
[Collection("db")]
public class TestClass1 : TestBase
{
public TestClass1(ITestOutputHelper testOutputHelper, DBfixture dbf) : base(testOutputHelper, dbf) { }
[Fact]
public void fact(){}
}
[Collection("db")]
public class TestClass2 : TestBase
{
public TestClass2(ITestOutputHelper testOutputHelper, DBfixture dbf) : base(testOutputHelper, dbf) { }
[Fact]
public void fact(){}
}
But when I run tests two DBfixture objects are created (one for each test class). Without collection four objects are created. How do I setup this so that one object is shared among all test classes?
You can use the collection fixture and add every test under that collection to achieve what you mentioned above. But if you use a single collection fixture then your entire test will run in serial unless you explicitly disable it in Xunitrunner config.
One of the point from Xunit Docs:
Test collections also influence the way xUnit.net runs tests when running them in parallel.
For more details please read:
https://xunit.net/docs/shared-context
Alternative can be, use a static class to store the DB context which you can assign while starting the test and use that across the test life cycle.

Why is AutoFixture executed more than once?

I've been using AutoFixture / AutoMoqData / Nunit for several months now, quite happily so far.
But I'm getting stuck on something weird:
If I want to run a single test in a test suite (using TestDriven), it seems that the AutoMoqData attribute is launched several times (between 5 and 9, but I don't really know why, and what decides how many times it runs).
The problem is that if I try to freeze an object instance in AutoFixture customizations, it'll end up freezing 5 to 9 objects, using this many fixture instances, and will have no clue which one is injected in my test.
Is there a way to avoid this ? Why does it happen in the first place ?
Sample code :
public class AutoMoqDataAttribute : AutoDataAttribute
{
public AutoMoqDataAttribute()
: base(new Fixture()
.Customize(new AutoMoqCustomization())
.Customize(new FrozenFooCustomization()) // freezing an object
.Customize(new FrozenFixtureCustomization()) // freezing the passed fixture to have the fixture instance available in the test body
.Customize(new StaticBindingCustomization()) // binding the frozen object to a static reference
)
{
}
}
public class FrozenFooCustomization : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Freeze<Foo>();
}
}
public class Foo { }
public class FrozenFixtureCustomization : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Inject(fixture);
}
}
public class StaticBindingCustomization : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Freeze<Mock<ISomeUtilities>>();
var someUtilities = fixture.Create<Mock<ISomeUtilities>>();
someUtilities.Setup(x => x.GetStuff()).Returns(fixture.Create<Foo>());
// this is executed several times, each time with a different instance of fixture, returning a different instance of Foo
SomeExtensions.Factory = x => someUtilities.Object;
// so the last "someUtilities.Object" is bound to the factory, but the test relies on a frozen version generated by one of the previous fixture instances
}
}
[TestFixture]
public class Test
{
[Test, AutoMoqData]
public void SomeTest(
[Frozen]Mock<ISomeUtilities> objMock,
SomeObjectToTest sut)
{
Assert.IsTrue(ReferenceEquals(objMock.Object.GetStuff(), sut.GetStuff()));
}
}
public class SomeObjectToTest { }
public static class SomeExtensions
{
public static Func<object, ISomeUtilities> Factory { get; set; } = x => new SomeUtilities(x);
public static object GetStuff(this object obj)
{
return Factory(obj).GetStuff();
}
}
public class SomeUtilities : ISomeUtilities
{
private readonly object _obj;
public SomeUtilities(object obj)
{
_obj = obj;
}
public object GetStuff()
{
return _obj; // whatever
}
}
public interface ISomeUtilities
{
object GetStuff();
}
EDIT: SomeExtensions.Factory is a factory used to make extensions mockable, based on Daniel Cazzulino's approach.
I'm not a big fan of those extensions and hope to refactor them at some point, but this is for another time. The question here is why are there several fixture instances, making the frozen SomeUtilities mock used in the factory different than the one used in the test, and thus the test to fail.
EDIT2: Following #MarkSeemann's advice, I reported an issue on Autofixture repo.

Testing multiple implementations of an interface in a single test class

I need to pass test data on class level but Theory and InlineData attributes can only be used on methods.
public class ContainerTests : TestFixture
{
private IContainer _container;
public ContainerTests(string containerName)
{
_container = CreateContainer(containerName);
}
[Fact]
public void ResolveJobFactory()
{
IJobFactory jobFactory = _container.Resolve<IJobFactory>();
}
private IContainer CreateContainer(string containerName)
{
if (containerName == "CastleWindsor")
{
return new WindsorContainerAdapter();
}
//other adapters
throw new NotImplementedException();
}
}
Is there a way to achieve something similar in xUnit.net?
Testing multiple implementations of an interface in a single test
class
Don't! Have a test class per implementation.
Edit: As per comments, I recommend having a base TestClass with all of the common tests, and then a Test Class per implementation which inherits from this base class.

MsTest ClassInitialize and Inheritance

I have a base class for my tests which is composed in the following way:
[TestClass]
public abstract class MyBaseTest
{
protected static string myField = "";
[ClassInitialize]
public static void ClassInitialize(TestContext context)
{
// static field initialization
myField = "new value";
}
}
Now I am trying to create a new test that inherits from the base, with the following signature:
[TestClass]
public class MyTest : MyBaseTest
{
[TestMethod]
public void BaseMethod_ShouldHave_FieldInitialized()
{
Assert.IsTrue(myField == "new value");
}
}
The ClassInitialize is never called by the child tests ... What is the real and correct way of using test initialization with inheritance on MsTest?
Unfortunately you cannot achieve this that way because the ClassInitializeAttribute Class cannot be inherited.
An inherited attribute can be used by the sub-classes of the classes that use it. Since the ClassInitializeAttribute cannot not be inherited, when the MyTest class is initialized the ClassInitialize method from the MyBaseTest class cannot be called.
Try to solve it with another way. A less efficient way is to define again the ClassInitialize method in MyTest and just call the base method instead of duplicating the code.
A potential workaround is to define a new class with AssemblyInitializeAttribute instead. It has a different scope, obviously, but for me it meets my needs (cross-cutting concerns, which just so happen to require exactly the same settings for every test class and test method.)
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace MyTests
{
[TestClass]
public sealed class TestAssemblyInitialize
{
[AssemblyInitialize]
public static void Initialize(TestContext context)
{
...
}
}
}
Use a static constructor on a base class? It's executed only once, by design, and it doesn't have the weird limitation on inheritance, like the ClassInitializeAttribute.
There is a parameter for the ClassInitialize and ClassCleanup attributes:
[ClassInitialize(InheritanceBehavior.BeforeEachDerivedClass)]
public static void ClassInitialize(TestContext context)
{
// gets called once for each class derived from this class
// on initialization
}
[ClassCleanup(InheritanceBehavior.BeforeEachDerivedClass)]
public static void Cleanup()
{
// gets called once for each class derived from this class
// on cleanup
}
which will actually do what you want.
UPDATE: Added lock to avoid multi-threading issues...
We know that a new instance of the class is constructed for every [TestMethod] in the class as it gets run. The parameter-less constructor of the base class will be called each time this happens. Couldn't you simply create a static variable in the base class and test it when constructor runs?
This helps you to not forget to put the initialization code in the sub-class.
Not sure if there's any drawback to this approach...
Like so:
public class TestBase
{
private static bool _isInitialized = false;
private object _locker = new object();
public TestBase()
{
lock (_locker)
{
if (!_isInitialized)
{
TestClassInitialize();
_isInitialized = true;
}
}
}
public void TestClassInitialize()
{
// Do one-time init stuff
}
}
public class SalesOrderTotals_Test : TestBase
{
[TestMethod]
public void TotalsCalulateWhenThereIsNoSalesTax()
{
}
[TestMethod]
public void TotalsCalulateWhenThereIsSalesTax()
{
}
}

used in multiple [TestFixture]s

I'm in the process of setting up tests in NUnit and have a newbie question.
Is it possible to have a Test/s that could be used in multiple [TestFixture]s?
So
[Test]ValidateString(string bob)
Could be called in a series of different [TestFixture]?
That doesn't sound like a test to me. Tests are typically parameterless (unless you're using [TestCase]s) and running it within a context of a single fixture would typically be enough -- it either passes once and that's good or it doesn't and it's a broken test.
If you just have a method that does some validation on a string, you could set it up as a static method on some class (e.g. TestHelpers) and call it from whatever tests (in multiple test fixtures) need it.
Here's another idea: inheritance. You can have a base fixture that has all your tests, and then fixtures that inherit from it that set up whatever variables you need. The tests will run for each fixture. I'm not familiar with Selenium RC, but you should be able to adapt the code below to set up whatever variables you need in various fixtures.
[TestFixture]
public class BaseFixtureTests
{
protected IMyClass _myClass;
[TestFixtureSetUp]
public void FixtureSetup()
{
_myClass = ConfigureMyClass();
}
protected virtual IMyClass ConfigureMyClass()
{
// fixtures that inherit from this will set up _myClass here as they see fit.
}
[Test]
public void MyClassTest1()
{
// test something about _myClass;
}
}
[TestFixture]
public class MySpecificFixture1 : BaseFixtureTests
{
protected override IMyClass ConfigureMyClass()
{
return new MySpecificMyClassImplementation();
}
}
public class MySpecificMyClassImplementation : IMyClass
{
//some implementation
}
You can also add extra tests in each fixture as well that don't test common functionality and don't need to be reused across fixtures.
The newer version of NUnit supports generics. This is a great fit if what you are testing doesn’t need to be configured (only created) from your test code. Here is an example copied from http://nunit.net/blogs/:
[TestFixture(typeof(ArrayList))]
[TestFixture(typeof(List<int>))]
public class IList_Tests<TList> where TList : IList, new()
{
private IList list;
[SetUp]
public void CreateList()
{
this.list = new TList();
}
[Test]
public void CanAddToList()
{
list.Add(1); list.Add(2); list.Add(3);
Assert.AreEqual(3, list.Count);
}
}
I’ve also used Anna’s approach of inheritance. One possible refinement to her example (depending on personal preference): Don’t mark the base class as a TestFixture, only the child classes. Each class that you mark as a TestFixture will be displayed as a set of tests in the NUnit client. You will probably never want to run the base class methods directly because the child is providing all of the setup code. If you remove TestFixture from the base class, running invalid tests won’t be an option in the UI. This allows you to run all the tests and see all green… always a nice feeling.
You might be able to achieve what you want with inheritance.
using NUnit.Framework;
namespace ClassLibrary1
{
[TestFixture]
public class TestFixtureBase
{
[SetUp]
public virtual void Setup()
{
// setup code here
}
[Test]
public void CommonTest1()
{
Assert.True(true);
}
[Test]
public void CommonTest2()
{
Assert.False(false);
}
}
public class MyClassTests : TestFixtureBase
{
[SetUp]
public override void Setup()
{
base.Setup();
// additional setup code
}
[Test]
public void MyClassTest1()
{
Assert.True(true);
}
}
}
You can write a method to be called from multiple [Test] methods. But I don't think there is a way to have the same [Test] included in multiple [TestFixture]s.
[TestFixture]
public class TestsOne{
[Test] public void TryOne(){
Helpers.ValidateString("Work?");
}
}
[TestFixture]
public class TestsTwo{
[Test] public void TryTwo(){
Helpers.ValidateString("Work?");
}
}
public static class Helpers{
public static void ValidateString(string s){
Assert.IsNotNull(s);
}
}

Categories

Resources