Testing multiple implementations of an interface in a single test class - c#

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.

Related

How to mock classes with internal constructors and static factory method?

I have class MyService that depends on ABCService (Nuget package/sdk)
public class MyService
{
private readonly ABCService _abc;
public MyService(ABCService abc)
{
this._abc = abc;
}
public async Task Run(string id)
{
// some logic
var result = await this._abc.DoSomething(id);
// some logic
}
}
ABCService looks something like this:
public class ABCService
{
internal ABCService(string someConnectionString, object someSettings)
{
// ... initialization
}
public static CreateFromConnectionString(string someConnectionString, object someSettings)
{
// some logic
return new ABCService(someConnectionString, someSettings);
}
}
Mocking class this way would not work and throws exception. "Parent does not have a default constructor."
var mock = new Mock<ABCService>();
var myService = new MyService(mock.Object);
How should I approach this? Is there a way to mock such classes?
The only thing that comes to my mind is creating interface IABCService and then injecting it in the constructor of MyService
public class IABCService
{
Task DoSomething(string id);
}
public class MyService
{
private readonly IABCService _abc;
public MyService(IABCService abc)
{
this._abc = abc;
}
}
And then I could do this:
var mock = new Mock<IABCService>();
var myService = new MyService(mock.Object);
Popular isolation frameworks such as Moq, NSubstitute or FakeItEasy are constrained. They can substitute only virtual methods. To use them, you will have to use the interface, as you already guessed. This is the recommended way to easily maintain loose coupling and testability.
There are bunch of unconstrained mocking frameworks: TypeMock Isolator, JustMock, Microsoft Fakes (all three are paid) and free open source Prig, Pose, Shimmy, Harmony, AutoFake, Ionad.Fody, MethodRedirect. They allow to mock non-virtual members, including private, static, etc.
Some of them allow you to work wonders, but you should not get too carried away with using them, because in the end it can lead to bad architecture.

Recursive class fixtures in C# xUnit

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(...)
}
}

Way to dynamically get repositories without a dependency on a DI container

I have a class that returns a repository (read only) using a generic method this is to reduce the number of repository classes I need to inject into classes in my business layer. It also allows me to add and use a new repo anywhere I have this wrapper class simply by adding a repo which implements IGenericReadRepo<T> as this will be registered in unity using the line Container.RegisterType(typeof(IGenericReadRepository<>), typeof(GenericReadRepository<>), new TransientLifetimeManager());. However this has is dependent on unity being the DI container. This smells to me.
public class ReadRepositoryWrapper : IReadRepositoryWrapper
{
private IUnityContainer _unityContainer;
public ReadRepositoryWrapper(IUnityContainer container)
{
_unityContainer = container;
}
public IGenericReadRepository<T> GetReadRepository<T>() where T : class
{
return _unityContainer.Resolve<IGenericReadRepository<T>>();
}
}
Can anyone think of a way to implement the GetReadRepository<T> without a the dependency on unity while not introducing any new dependencies. Or can someone think of another way to get repositories without having bloated constructors or a dependency on my context.
You can create generic factory interfaces/classes for dynamic object creation. Many DI containers support object creation using lambda expressions.
public interface IFactory<T>
{
T Create();
}
public class Factory<T> : IFactory<T>
{
private readonly Func<T> _creator;
public Factory(Func<T> creator)
{
if(creator == null)
throw new ArgumentNullException("creator");
_creator = creator;
}
public T Create()
{
return _creator();
}
}
The generic factory interface than can be injected into the consuming classes.
public class ReadRepositoryWrapper<T> : IReadRepositoryWrapper<T> where T : class
{
private readonly IFactory<IGenericReadRepository<T>> _factory;
public ReadRepositoryWrapper(IFactory<IGenericReadRepository<T>> factory)
{
if(factory == null)
throw new ArgumentNullException("factory");
_factory = factory;
}
public IGenericReadRepository<T> GetReadRepository()
{
return _factory.Create();
}
}
Or something like that.

How to register open generic type by interface with Castle Windsor?

I'm trying to make this registration work. I have a number of IEventFactory<> responsible for creating different (external) events within my application.
I'd like to resolve all kinds of factories just by it's interface, eg IEventFactory<ClassA>. How do I make my test below succeed?
[TestFixture]
public class WindsorTests
{
[Test]
public void Test_factory_registration()
{
WindsorContainer container = new WindsorContainer();
container.AddFacility<TypedFactoryFacility>();
container.Register(AllTypes.FromThisAssembly().BasedOn(typeof(IEventFactory<>)).WithService.AllInterfaces());
IEventFactory<ClassA> factoryA = container.Resolve<IEventFactory<ClassA>>();
IEventFactory<ClassB> factoryB = container.Resolve<IEventFactory<ClassB>>();
}
class ClassA
{
}
class ClassB
{
}
interface IEventFactory<TCaller>
{
void Foo();
}
class EventFactoryA : IEventFactory<ClassA>
{
public void Foo()
{
throw new NotImplementedException();
}
}
class EventFactoryB : IEventFactory<ClassB>
{
public void Foo()
{
throw new NotImplementedException();
}
}
}
Your interfaces and factories are private. Either make them public/internal or add IncludeNonPublicTypes() in the registration line.
To add to what #Patrick Steele said, you probably also should be using .WithService.Base()
Have a look at the documentation which details the differences.

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