I try to create a good testable repository class to use with Moq. I don't want duplicate my selector methods (GetAll, Get, ...). My implementation works fine but SonarSource reports an error RSPEC-1699 Does anyone know of a better implementation?
var areas = new Area[] { ... };
var areaRepositoryMock = new Mock<BaseAreaRepository>() { CallBase = true };
areaRepositoryMock.Setup(m => m.Initialize()).Returns(areas);
Base Class
public abstract class BaseAreaRepository
{
protected Area[] _areas;
protected BaseAreaRepository()
{
this._areas = this.Initialize();
}
public abstract Area[] Initialize();
public Area[] GetAll()
{
return this._monitoredAreas;
}
public Area Get(int id)
{
return this._areas.FirstOrDefault(o => o.Id.Equals(id));
}
}
MyAreaRepository
public class MyAreaRepository : BaseAreaRepository
{
public override Area[] Initialize()
{
return //Load data from an other source
}
}
The RSPEC-1699 Constructors should only call non-overridable methods doens't have anything with the unit tests it will remain there regardless how you are going to test it.
Does anyone know of a better implementation?
I would like to propose another approach in order to avoid this violation and make your code even more testable.
The idea is instead of the base class use composition and DI principle.
public interface IAreaContext
{
Area[] GetAreas();
}
public class AreaRepository
{
private IAreaContext _areaContext;
protected BaseAreaRepository(IAreaContext areaContext)
{
_areaContext = areaContext;
}
public Area[] GetAll()
{
return _areaContext.GetAreas();
}
}
Then you could define multiple implementations of IAreaContext and injext:
public class MyAreaContext : IAreaContext
{
public Area[] GetAreas()
{
return //Load data from an other source
}
}
public class MyOtherAreaContext : IAreaContext
{
public Area[] GetAreas()
{
return //Load data from an other source
}
}
Now when you have this setup repository could be easily testable for different behaviors of the context itself. This is just an example to demonstrate idea:
//Arrange
var context = new Mock<IAreaContext>();
context.Setup(m => m.GetAreas()).Verifiable();
var sut = new AreaRepository(context.Object);
//Act
var _ = sut.GetAll();
//Assert
context.Verify();
If you want to test just the base class, then I would create a unit test specific implementation of the class, and just provide any helper functions to test the protected ones. Basically what you have done with MyAreaRepository but as a private class within the test class.
Related
I have implemented array based Stack Data Structure along with corresponding Unit Tests. This Stack implements my IStack interface. So at the moment, my UT class looks something like that:
[TestClass]
public class Stack_ArrayBased_Tests
{
//check against empty collection
[TestMethod]
public void IsEmpty_NoElements()
{
var myStack = new Stack_ArrayBased_Example1(10);
var exp = true;
var act = myStack.IsEmpty();
Assert.AreEqual(exp, act);
}
Now, I am about to implement Linked List based Stack. This Stack will inherit from the same IStack interface.
I would like to Unit Test the linked list Stack as well. Since both are inheriting from the same interface, I should be able to take advantage of already implemented Unit Test, in order to prevent from unnecessary code duplication.
What would be the best way to create two separate Unit Test classes, one for Array based Stack, and another for Linked List based Stack, that would use the same Unit Test methods? I assume Dependency Injection would be an answer, but how I would go about it?
Dependency injection is never the answer when it comes to tests.
You are not testing abstractions, that's impossible, you test concrete implementations. You can however mock abstractions, interfaces, abstract classes.
You can create some class with the sole purpose of reusing code and you call that class from your test methods, that's ok and totally doable.
You will still need two test classes, one for each of your concrete implementations, and have both call this new class you created. This avoids code duplication.
You can separate logic in another method.
[TestMethod]
public void IsEmpty_NoElements_ArrayBased()
{
var myStack = new Stack_ArrayBased_Example1(10);
IsEmpty_NoElements(myStack)
}
[TestMethod]
public void IsEmpty_NoElements_LinkedListBased()
{
var myStack = new Stack_LinkedListBased_Example1(10);
IsEmpty_NoElements(myStack)
}
public void IsEmpty_NoElements(IStack myStack)
{
var exp = true;
var act = myStack.IsEmpty();
Assert.AreEqual(exp, act);
}
Say we have the following
public interface IStack
{
bool IsEmpty { get; }
}
public class StackImpl1 : IStack
{
public StackImpl1(int size)
{
IsEmpty = true;
}
public bool IsEmpty { get; }
}
public class StackImpl2 : IStack
{
public StackImpl2(int size)
{
IsEmpty = true;
}
public bool IsEmpty { get; }
}
And we wish to implement the IsEmpty_OnCreation() test from the OP. We can make a common test and add multiple invokers (one for each implementation to be tested). The problem is scaling.
For each new piece of functionality to be tested we need to add
1) the test implementation
2) an invoker for each implementation to be tested.
For each new implementation we introduce, we need to add an invoker for each existing test.
It is possible to use inheritance to do most of the work for us
public abstract class StackTest
{
protected abstract IStack Create(int size);
[TestMethod]
public void IsEmpty_NoElements()
{
var myStack = Create(10);
var exp = true;
var act = myStack.IsEmpty;
Assert.AreEqual(exp, act);
}
}
[TestClass]
public class StackImp1Fixture : StackTest
{
protected override IStack Create(int size)
{
return new StackImpl1(size);
}
}
[TestClass]
public class StackImp2Fixture : StackTest
{
protected override IStack Create(int size)
{
return new StackImpl2(size);
}
}
The tests are generated in each derived fixture.
If we want to add a new test, we add it to the StackTest class and it is automatically included in each derived fixture.
If we add a third implementation of IStack , we simply add a new test fixture deriving from StackTest and overriding the create method.
Note:
If the classes under test have default constructors, the same shape can be used with a Generic StackTest as the base
public class GenStackTest<TStack> where TStack : IStack, new()
{
[TestMethod]
public void IsEmpty_NoElements()
{
var myStack = new TStack();
var exp = true;
var act = myStack.IsEmpty;
Assert.AreEqual(exp, act);
}
}
[TestClass]
public class GenStack1Fixture : GenStackTest<StackImpl1>
{
}
[TestClass]
public class GenStack2Fixture : GenStackTest<StackImpl2>
{
}
I have a controller which contains a business class that internally has dependencies to a datahandler. For testing that business class I need to mock the datahandler. After setup, I am assigning the business class' datahandler with the mocked datahandler. But while debugging, the business class' datahandler is showing null , I know that I should use the constructor to inject the mocked object.But is it possible to do it without using any constructor injection ?Can any body help me with this?
my business class:
public class FooBusiness
{
public static BarDataHandler _barDatahandler = new BarDataHandler();
...
}
Test class:
public class FooBusinessTest
{
...
_mockedBarDataHandler = new Mock<IBarDataHandler>(){CallBase:true};
public FooTestMeth()
{
//Arrange
_mockedBarDataHandler.Setup(x=>x.Search(It.IsAny<int>).Returns(1);
...
FooBusiness _fooBusiness = new FooBusiness();
FooBusiness._barDatahandler = _mockedBarDataHandler.Object;
//Act
...
}
}
As I mentioned, there are multiple ways to achieve your needs.
Personally I like Shyju's answer more (Constructor Injection), but if you can't change the constructor, you can still change the implementation afterwards by setting the property:
business class:
public class FooBusiness
{
private IBarDataHandler _barDatahandler = new BarDatahandler();
public IBarDataHandler BarDatahandler
{
get { return _barDatahandler; }
set { _barDatahandler = value; }
}
public int Search(int a)
{
return _barDatahandler.Search(a);
}
}
Test class:
public class FooBusinessTest
{
_mockedBarDataHandler = new Mock<IBarDataHandler>(){CallBase:true};
public FooTestMeth()
{
//Arrange
_mockedBarDataHandler.Setup(x => x.Search(It.IsAny<int>).Returns(1);
FooBusiness fooBusiness = new FooBusiness();
fooBusiness.BarDatahandler = _mockedBarDataHandler.Object;
//Act
}
}
If you worry about to refactor the implementation, it is better to setup all the tests first. After that you can refactor with a safer feeling :)
You need to inject your dataHandler dependency to FooBusiness
You need to extract an interface for your BarDataHandler if one does not exist.
interface IBarDataHandler
{
string GetUserToken(int id);
}
public class BarDataHandler : IBarDataHandler
{
public string GetUserToken(int id)
{
// to do :read from db and return
}
}
And add a constructor to FooBusiness class which accepts an implementation of IBarDataHandler.
public class FooBusiness
{
IBarDataHandler barDataHandler;
public FooBusiness(IBarDataHandler barDataHandler)
{
this.barDataHandler=barDataHandler
}
public string GetUserToken(int id)
{
return this.barDataHandler.GetUserToken(id);
}
}
You can use any one of the dependency injection frameworks like Unity/Ninject/StructureMap to resolve your concrete implementation when your app runs.
You can use any mocking framework like Moq to mock the fake implementation of IBarDataHandler in your unittests.
stupid question possibly, first time I'm actually writing a unit test at all (shame on me). I'm using Xunit and AutoFixture.
So, I have some unit tests that I would like to run with different combinations of input data.
For example, say I'm testing my DAL and want to test the same unit test with different types of repositories (e.g. in-memory and SQL). I also need to have some other data created, which will be used both by the unit test as well as the repository.
Some of my classes need to be created via factory methods, as they don't have any public constructors.
My ideal would be do to something like
[Theory, InMemoryRepository, SomeOtherData]
[Theory, SqlRepository, SomeOtherData]
// ... some other data combinations ...
public void SomeTest(IRepository repository, ISomeOtherData someOtherData)
{
// do some tests here
}
public class InMemoryRepositoryAttribute : AutoDataAttribute
{
public InMemoryRepositoryAttribute()
{
Fixture.Register<IRepository>(CreateRepository);
}
protected IRepository CreateRepository()
{
var data = Fixture.CreateMany<ISomeOtherData>().ToList(); // this will throw an exception "AutoFixture was unable to create an instance (...)" as my binding doesn't seem be available in the Fixture
var repository = new InMemoryDAL.Repository();
repository.Insert(data);
return repository;
}
}
public class SomeOtherDataAttribute : AutoDataAttribute
{
public SomeOtherDataAttribut()
{
Fixture.Register<ISomeOtherData>(CreateData);
}
protected ISomeOtherData CreateData()
{
string test = Fixture.Create<string>();
var data = (new SomeOtherDataFactory()).Create(test);
return data;
}
}
but this doesn't work, as both my AutoDataAttribute-classes seem to be based on seperate fixtures. I.e. whatever I register in my SomeOtherDataAttribute doesn't seem to be available in my InMemoryRepositoryAttribute instance.
Is there any way to fix this & use attributes to combine different sets of data in a Fixture?
Or what alternatives would you suggest - maybe best to create individual test functions for each data combination, and call SomeTest() explicitly from there?
Thanks!
Actually, you can achieve this by defining a custom AutoDataAttribute that allows supply array of customizations types. Here is a example of how to accomplish this task:
public class CompositeCustomizationsAttribute : AutoDataAttribute
{
public CompositeCustomizationsAttribute(params Type[] customizationTypes)
{
foreach (var type in customizationTypes)
{
var customization = (ICustomization)Activator.CreateInstance(type);
Fixture.Customize(customization);
}
}
}
public class InMemoryRepositoryCustomization : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Register<IRepository>(() => CreateRepository(fixture));
}
protected IRepository CreateRepository()
{
var data = Fixture.CreateMany<ISomeOtherData>().ToList();
var repository = new InMemoryDAL.Repository();
repository.Insert(data);
return repository;
}
}
public class SomeOtherDataCustomization : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Register<ISomeOtherData>(() => CreateData(fixture));
}
protected ISomeOtherData CreateData()
{
string test = Fixture.Create<string>();
var data = (new SomeOtherDataFactory()).Create(test);
return data;
}
}
Given above customizations and CompositeCustomizationsAttribute you can now define your test method :
[Theory, CompositeCustomizations(typeof(InMemoryRepositoryCustomization), typeof(SomeOtherDataCustomization))]
public void SomeTest(IRepository repository, ISomeOtherData someOtherData)
{
// do some tests here
}
I'm using moq.dll
When I mock a class(all the IRepository interface) i use this line code
int state = 5;
var rep = new Mock<IRepository>();
rep.Setup(x => x.SaveState(state)).Returns(true);
IRepository repository = rep.Object;
but in this case i mock all the function in repository class.
Then all the methods in class repository are substituted with the methods setup of Mock dll
I want use all the methods defined in class repository(the real class) and mock only one function(SaveState)
How can I do this? Is possible?
You can create an instance of the real repository, then use the As<>() to obtain the desired interface, which you can then override with the setup, like this:
var mockRep = new Mock<RealRepository>(ctorArg1, ctorArg2, ...)
.As<IRepository>();
mockRep.Setup(x => x.SaveState(state)).Returns(true);
Then mockRep.Object as the repository dependency to the class under test.
Note that you will only be able to Mock methods on the Interface*, or virtual methods, in this way.
Update : *This might not work in all scenarios, since .Setup will only work on virtual methods, and C# interface implementations are "virtual" and sealed by default. And using As() will prevent the partial mock behaviour.
So it appears that the RealRepository concrete class will need to implement the IRepository interface with virtual methods in order for the partial mock to succeed, in which case CallBase can be used for the wire-up.
public interface IRepo
{
string Foo();
string Bar();
}
public class RealRepo : IRepo
{
public RealRepo(string p1, string p2) {Console.WriteLine("CTOR : {0} {1}", p1, p2); }
// ** These need to be virtual in order for the partial mock Setups
public virtual string Foo() { return "RealFoo"; }
public virtual string Bar() {return "RealBar"; }
}
public class Sut
{
private readonly IRepo _repo;
public Sut(IRepo repo) { _repo = repo; }
public void DoFooBar()
{
Console.WriteLine(_repo.Foo());
Console.WriteLine(_repo.Bar());
}
}
[TestFixture]
public class SomeFixture
{
[Test]
public void SomeTest()
{
var mockRepo = new Mock<RealRepo>("1st Param", "2nd Param");
// For the partially mocked methods
mockRepo.Setup(mr => mr.Foo())
.Returns("MockedFoo");
// To wireup the concrete class.
mockRepo.CallBase = true;
var sut = new Sut(mockRepo.Object);
sut.DoFooBar();
}
}
I came to this page because I had exactly the same problem: I needed to mock a single method, which was relying on many external sources and could produce one of three outputs, while letting the rest of the class do its work. Unfortunately the partial mock approach proposed above did not work. I really don't know why it did not work. However, the main problem is that you can't debug inside such mocked class even if you put break points where you want. This is not good because you might really need to debug something.
So, I used a much simpler solution: Declare all methods that you want to mock as virtual. Then inherit from that class and write one-liner mock overrides to return what you want, for example:
public class Repository
{
/// <summary>
/// Let's say that SaveState can return true / false OR throw some exception.
/// </summary>
public virtual bool SaveState(int state)
{
// Do some complicated stuff that you don't care about but want to mock.
var result = false;
return result;
}
public void DoSomething()
{
// Do something useful here and assign a state.
var state = 0;
var result = SaveState(state);
// Do something useful with the result here.
}
}
public class MockedRepositoryWithReturnFalse : Repository
{
public override bool SaveState(int state) => false;
}
public class MockedRepositoryWithReturnTrue : Repository
{
public override bool SaveState(int state) => true;
}
public class MockedRepositoryWithThrow : Repository
{
public override bool SaveState(int state) =>
throw new InvalidOperationException("Some invalid operation...");
}
That's all. You can then use your mocked repos during unit tests AND you can debug anything you need. You can even leave the protection level below public so that not to expose what you don't want to expose.
I have multiple classes that implement the same interface, how should I write unit tests to verify that each class implements the interface correctly, keeping code duplication to a minimum (DRY)?
As an example of what I mean, the following is a very basic library containing two implementations of IDeleter: Deleter1 and Deleter2. Both implement the method Delete by calling Delete on their associated IRepository.
using Microsoft.Practices.Unity;
namespace TestMultiple
{
public interface IRepository
{
void Delete(string id);
}
public abstract class Baseclass
{
protected abstract IRepository GenericRepository { get; }
public void Delete(string id)
{
GenericRepository.Delete(id);
}
}
public interface IDeleter
{
void Delete(string id);
}
public interface IRepository1 : IRepository
{
}
public abstract class RepositoryBase
{
public void Delete(string id)
{
}
}
public class Repository1 : RepositoryBase, IRepository1
{
}
public class Deleter1 : Baseclass, IDeleter
{
protected override IRepository GenericRepository { get { return Repository; } }
[Dependency]
public IRepository1 Repository { get; set; }
}
public interface IRepository2 : IRepository
{
}
public class Repository2 : RepositoryBase, IRepository2
{
}
public class Deleter2 : Baseclass, IDeleter
{
protected override IRepository GenericRepository { get { return Repository; } }
[Dependency]
public IRepository2 Repository { get; set; }
}
}
For these two classes, Deleter1 and Deleter2, I have written two corresponding unit test classes as shown in the below snippet. The tests check the same behaviour, i.e. that Delete is called on the underlying repository. Is there some better way to implement the same tests for all implementations of IDeleter? For example, should I write a baseclass containing common test methods, such as TestDelete, for TestDeleter1 and TestDeleter2?
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.Practices.Unity;
using Moq;
namespace TestMultiple.Tests
{
[TestClass]
public class TestDeleter1
{
[TestMethod]
public void TestDelete()
{
var mockRepo = new Mock<IRepository1>();
var container = new UnityContainer().RegisterInstance<IRepository1>(mockRepo.Object);
var deleter = container.Resolve<Deleter1>();
deleter.Delete("id");
mockRepo.Verify(r => r.Delete("id"));
}
}
[TestClass]
public class TestDeleter2
{
[TestMethod]
public void TestDelete()
{
var mockRepo = new Mock<IRepository2>();
var container = new UnityContainer().RegisterInstance<IRepository2>(mockRepo.Object);
var deleter = container.Resolve<Deleter2>();
deleter.Delete("id");
mockRepo.Verify(r => r.Delete("id"));
}
}
}
EDIT:
Feel free to mention unit test frameworks that may help solve this kind of problem, although my preference is with NUnit.
There's no easy way to write tests in the frameworks I'm aware of that assert common behaviour on interfaces. The best you can do is write tests and helper methods as if you were testing an abstract class and then insert the real type into derived test classes.
For example, you could create an DeleterTests class, which provides tests for the interface:
public abstract class DeleterTests<TRepository> where TRepository : IRepository
{
[TestMethod]
public void TestDelete()
{
var mockRepo = new Mock<TRepository>();
var container = new UnityContainer();
container.RegisterInstance<TRepository>(mockRepo.Object);
var deleter = this.CreateDeleter(container);
deleter.Delete("id");
mockRepo.Verify(r => r.Delete("id"));
}
protected abstract IDeleter CreateDeleter(IUnityContainer container);
}
Then, you inherit from this class for anything implementing IDeleter, implementing the abstract CreateDeleter method as you need to:
public class Deleter1Tests : DeleterTests<IRepository1>
{
protected override IDeleter CreateDeleter(IUnityContainer container)
{
return container.Resolve<Deleter1>();
}
}
public class Deleter2Tests: DeleterTests<IRepository2>
{
protected override IDeleter CreateDeleter(IUnityContainer container)
{
return container.Resolve<Deleter2>();
}
}
If you needed to compose the instances differently, you could implement the abstract CreateDeleter in any fashion.
You should write unit test for each class, not really worrying about other implementations. If you feel like you write the same tests again and again, it is propably because your production code is un-DRY -- not your test code. As others have pointed out; if the different implementations have a lot in comon, some common abstract ancestor is probably a good idea.
If all of your classes should implement the IDeleter interface identically, your base class should not be abstract. Implement the IDeleter interface in the base class, that way all of the child classes inherit the same implementation from the base. If there is an edge case where a different implementation is desired, that class can then override the base class' implementation.