Unit Testing BLL: mock Repository, UnitOfWork, UnitOfWorkFactory - unit-testing

I need a jump start in testing the methods on my Business layer. Consider the Materials BLL object, how can I test the AddNewMaterial method for it?
interface IGenericRepository<TEntity>
{
TEntity Add(TEntity m);
}
public interface IMaterialRepository : IGenericRepository<Material>
{
}
public interface IUnitOfWork
{
IMaterialRepository Materials { get; private set;}
void Save();
}
public interface IUnitOfWorkFactory
{
IUnitOfWork GetUnitOfWOrk();
}
public class MaterialsBLL
{
private readonly IUnitOfWorkFactory _uowFactory;
//uowFactory comes from DI
public MaterialsBLL(IUnitOfWorkFactory uowFactory)
{
_uowFactory = uowFactory;
}
//TODO: test this
public Material AddNewMaterial(Material m)
{
using(var uow = _uowFactory.GetUnitOfWOrk())
{
var result = uow.Materials.Add(m);
uow.Save();
return result;
}
}
I am using Moq, and XUnit, but am very green. In general I want to do this:
Mock the repositories Add method.
Mock the UoW Materials property to return my repository mock.
Mock the UoWFactory to return the UoW mock.
Create the MaterialsBLL giving the mocked UoWFactory to the contstructor.
Verify that the AddNewMaterials calls the repository's Add, and the UoW's Save, etc.
It seems to me that, I maybe should be creating a Fake MaterialRepository, rather than mocking it? Any other advice? Here is a first crack:
[Fact]
public void TestGetMaterialById()
{
var materialList = GetMaterials();
var materialRepositoryMock = new Mock<IMaterialRepository>();
materialRepositoryMock.Setup(repo => repo.Get(4)).Returns(materialList.First());
var uowMock = new Mock<IUnitOfWork>();
uowMock.SetupProperty<IMaterialRepository>(uow => uow.Materials, materialRepositoryMock.Object);
var uowFactoryMock = new Mock<IUnitOfWorkFactory>();
uowFactoryMock.Setup(f => f.GetUnitOfWork()).Returns(uowMock.Object);
var materialsBll = new Materials(uowFactoryMock.Object);
var result = materialsBll.Get(4);
Assert.Equal(result.MaterialId, 4);
Assert.Equal(result.Name, "Four");
}

When you feel like you need several levels of nested mock objects, there's generally something wrong with your design.
The Law of Demeter warns us here that you should probably not tinker with uow.Materials in MaterialsBLL.
Besides, a Unit of Work is typically not the place to expose Repositories. The code that needs to access Materials will usually have a direct reference to an IMaterialsRepository, not ask it from the UoW, and then the Repository implementation might reference the UoW internally.
This leads to a flatter design and simplifies your production code as well as your tests.

Related

AutoFixture + NSubstitute + Virtual methods

Wanting to know if there's a way to mock a virtual method on a concrete class using AutoFixture and NSubstitute. I've been able to do this easily with Moq, as can be seen here:
public class SomeConcreteClass
{
public string MethodA()
{
return MethodB();
}
public virtual string MethodB()
{
return "AAA";
}
}
[TestFixture]
public class SomeConcreteClassTests
{
private IFixture _fixture;
private SomeConcreteClass _someConcreteClass;
[SetUp]
protected void Setup()
{
_fixture = new Fixture()
.Customize(new AutoMoqCustomization());
var someConcreteClassMock = _fixture.Create<Mock<SomeConcreteClass>>();
_someConcreteClass = someConcreteClassMock.Object;
someConcreteClassMock.CallBase = true;
}
[Test]
public void SomeScenario()
{
Mock.Get(_someConcreteClass).Setup(m => m.MethodB()).Returns("BBB");
var actual = _someConcreteClass.MethodA();
actual.ShouldBe("BBB");
}
}
This is best achieved if you use AutoFixture's support for Parametrised Tests, here illustrated using xUnit.net (but, IIRC, there's similar support for NUnit):
[Theory, AutoNSubstituteData]
public void ImplicitSubtituteViaAttribute([Substitute]SomeConcreteClass scc)
{
scc.MethodB().Returns("BBB");
var actual = scc.MethodB();
Assert.Equal("BBB", actual);
}
Using the [Substitute] attribute enables you to explicitly tell AutoFixture that, although you asked for a concrete class, it should create it via NSubstitute so that you can override any virtual members it might have.
AutoNSubstituteData is defined like this:
public class AutoNSubstituteDataAttribute : AutoDataAttribute
{
public AutoNSubstituteDataAttribute() :
base(() => new Fixture().Customize(new AutoNSubstituteCustomization()))
{
}
}
AutoDataAttribute comes from AutoFixture.Xunit2, but if you prefer NUnit over xUnit.net, you should be able to use AutoFixture.NUnit3 instead.
Otherwise, I'm not sure you can achieve exactly the same result as with AutoFixture.AutoMoq. In this degenerate example, you can do this:
[Fact]
public void ImperativeWorkaround()
{
var fixture = new Fixture().Customize(new AutoNSubstituteCustomization());
fixture.Register(() => Substitute.For<SomeConcreteClass>());
var scc = fixture.Create<SomeConcreteClass>();
scc.MethodB().Returns("BBB");
var actual = scc.MethodB();
Assert.Equal("BBB", actual);
}
This is, however, fairly pointless, as you could just as well have written this:
[Fact]
public void Reduction()
{
var scc = Substitute.For<SomeConcreteClass>();
scc.MethodB().Returns("BBB");
var actual = scc.MethodB();
Assert.Equal("BBB", actual);
}
In other words, AutoFixture doesn't actually do anything in that workaround.
I could imagine that the real issue is that in real usage, the concrete class in question has other members or constructor data that you wish to fill with data. The problem is that due to the way NSubstitute is designed, I'm not aware of any way you can declaratively ask for a 'substitute'; you'll have to use the Substitute.For method, which then completely short-circuits AutoFixture's ability to hook into the process and add its own behaviour.
With Moq, this is possible because in the OP, you're not asking AutoFixture for a SomeConcreteClass object, but rather for a Mock<SomeConcreteClass>, and that enables AutoFixture to distinguish.
In other words, Moq follows the Zen of Python that explicit is better than implicit, and that makes it extensible to a degree not easily achieved with NSubstitute. For that reason, I've always considered Moq to have the better API.

How to unit test a service call in xUnit and nSubstitute

I been trying to figure out how i can unit test service and so far have got nowhere.
I am using xUnit and NSubstitute (as advised by friends), below is the simple test that i want to run (which fails currently).
public class UnitTest1
{
private readonly RallyService _rallyService;
public UnitTest1(RallyService rallyService)
{
_rallyService= rallyService;
}
[Fact]
public void Test1()
{
var result = _rallyService.GetAllRallies();
Assert.Equal(2, result.Count());
}
}
My rally service class makes a simple call to the db to get all Rally entites and returns those:
public class RallyService : IRallyService
{
private readonly RallyDbContext _context;
public RallyService(RallyDbContext context)
{
_context = context;
}
public IEnumerable<Rally> GetAllRallies()
{
return _context.Rallies;
}
}
Any guidance would be appreciated.
Since you use .NET Core, I assume you also use Entity Framework Core. While it was possible to mock most of the operations in the previous EF version, however the EF Core suggests to use in-memory database for unit testing. I.e. you don't need to mock RallyDbContext, hence NSubstitute is not needed for this particular test. You would need NSubstitute to mock the service when testing a controller or application using the service.
Below is your Test1 written using in-memory database.
public class UnitTest1
{
private readonly DbContextOptions<RallyDbContext> _options;
public UnitTest1()
{
// Use GUID for in-memory DB names to prevent any possible name conflicts
_options = new DbContextOptionsBuilder<RallyDbContext>()
.UseInMemoryDatabase(Guid.NewGuid().ToString())
.Options;
}
[Fact]
public async Task Test1()
{
using (var context = new RallyDbContext(_options))
{
//Given 2 records in database
await context.AddRangeAsync(new Rally { Name = "rally1" }, new Rally { Name = "rally2" });
await context.SaveChangesAsync();
}
using (var context = new RallyDbContext(_options))
{
//When retrieve all rally records from the database
var service = new RallyService(context);
var rallies = service.GetAllRallies();
//Then records count should be 2
Assert.Equal(2, rallies.Count());
}
}
}
A working test application with this unit test is in my GitHub for your reference. I used SQL Express in the actual app.
I don't think it is standard to have a unit test constructor with a parameter. The unit test runner will new up this class, and unless you are using something that will auto-inject that parameter I think the test will fail to run.
Here is a standard fixture layout:
public class SampleFixture {
[Fact]
public void SampleShouldWork() {
// Arrange stuff we need for the test. This may involved configuring
// some dependencies, and also creating the subject we are testing.
var realOrSubstitutedDependency = new FakeDependency();
realOrSubstitutedDependency.WorkingItemCount = 42;
var subject = new Subject(realOrSubstitutedDependency);
// Act: perform the operation we are testing
var result = subject.DoWork();
// Assert: check the subject's operation worked as expected
Assert.Equal(42, result);
}
[Fact]
public void AnotherTest() { /* ... */ }
}
If you need a common setup between tests, you can use a parameterless constructor and do common initialisation there.
In terms of the specific class you are trying to test, you need to make sure your RallyDbContext is in a known state to repeatably and reliably test. You may want to look up answers specific to testing Entity Framework for more information.

Castle Windsor: unit test component lifecycle

I would like to write a non-regression test to validate that transient components are well released. Some are created by a direct injection in ctor, other by typed factories.
I thought that I could do this way:
// Given
var rootComponent = container.Resolve<IRootComponent>();
var c1 = rootComponent.C1;
var c2 = c1.C2;
etc.
Assert.True(Container.Kernel.ReleasePolicy.HasTrack(c1));
Assert.True(Container.Kernel.ReleasePolicy.HasTrack(c2));
// When
c1.Close();
// Then
Assert.False(Container.Kernel.ReleasePolicy.HasTrack(c1));
Assert.False(Container.Kernel.ReleasePolicy.HasTrack(c2));
HasTrack() always returns false, although if I look at the container in debug mode, I can see my components well tracked. Why is that? Do you have any suggestion for such a test?
Thx for your help
The reason that your components are not tracked is that the component and it's dependencies have no decomissioning requirements. In this case there is no reason for windsor to track them.
When using windsor in general you should only resolve on your container once to obtain your top level component. All other component are either injected or created by a factory. There is no need to worry about the live time of injected components. The container will handle it for you.
For transient components that you create with a factory you should be aware that they will never live (be tracked) longer then the factory it self. So if you don't mind that your components live at long as your factory there is no need to release them (using a destroy method on a factory).
For component that I want to make sure that I release them, I generally I create unit test for which I stub out the factory. That way it is easy to test that destroy is called.
I think with the approach that you are taking you are not just testing your code but also the container. IMHO windsor is already well tested, and test should focus on your own code.
Good luck,
Marwijn.
Two years too late, but here's a test.
public class DependsOnSomethingDisposable
{
private readonly SomethingDisposable _disposable;
public Boolean SomethingDisposableIsDisposed { get { return _disposable.Disposed; } }
public DependsOnSomethingDisposable(SomethingDisposable disposable)
{
_disposable = disposable;
}
}
public class SomethingDisposable : IDisposable
{
public Boolean Disposed { get; private set; }
public void Dispose()
{
Disposed = true;
}
}
[TestClass]
public class WindsorLifestyleTests
{
private IWindsorContainer _container;
[TestInitialize]
public void Setup()
{
_container = new WindsorContainer();
}
[TestCleanup]
public void Cleanup()
{
_container.Dispose();
}
[TestMethod]
public void TransientDependencyIsDisposed()
{
_container.Register(
Component.For<DependsOnSomethingDisposable>().LifestyleTransient(),
Component.For<SomethingDisposable>().LifestyleTransient()
);
var resolved = _container.Resolve<DependsOnSomethingDisposable>();
_container.Release(resolved);
Assert.IsTrue(resolved.SomethingDisposableIsDisposed);
}
[TestMethod]
public void NonTransientDependencyIsNotDisposed()
{
_container.Register(
Component.For<DependsOnSomethingDisposable>().LifestyleTransient(),
Component.For<SomethingDisposable>().LifestyleSingleton()
);
var resolved = _container.Resolve<DependsOnSomethingDisposable>();
_container.Release(resolved);
Assert.IsFalse(resolved.SomethingDisposableIsDisposed);
}
}

Interaction testing using moles

How can you verify interaction test using Moles. For example the following test is written using rhino mock. Can anyone please tell me how can I achive the same using moles? Is there anything like verify for moles?
[Test]
public void MyTest()
{
MockRepository mocks = new MockRepository();
ILogger mockLogger = mocks.StrictMock<ILogger>();
using(mocks.Record())
{
mockLogger .Log("this is my error");
}
MyClass mc = new MyClass (mockLogger);
mc.MyFunc("abcd");
mocks.Verify(mockLogger);
}
class MyClass
{
private ILogger logger;
public MyClass(ILogger logger)
{ this.logger = logger; }
public void MyFunc(string str)
{
logger.log("this is my error");
}
}
I would really appreciate your help.
Personally, I use Moq for internal dependency and Moles for externalities (and unpleasant static stuff forced on me by others), so I might not be giving you the best way, but it's a way:
[TestMethod, Owner("ebd"), TestCategory("Proven"), TestCategory("Unit")]
public void MyTest()
{
var myCalled = false;
var myLogger = new SILogger();
myLogger.LogString = (s) => myCalled = true;
var myClass = new MyClass(myLogger);
myClass.MyFunc("abcd");
Assert.IsTrue(myCalled);
}
Key idea here is "SILogger" which is your stub for ILogger. You then set up instance behavior for it's "LogString" (which corresponds to your log(string) method. You set it to callback your local variable and set it to true. You then invoke the method that should invoke log, and you assert that your local is now true.
Again, I'd usually do this with Moq and used myStub.Verify() for this purpose, so it's possible that there's a slicker way to do this with moles that I'm not aware of. Personally, I think Moles is much better suited for "mocking the unmockable", and I prefer a combination of Moq (for my own interfaces and classes) and Moq (for framework and externalities like File I/O, GUI, Db connections, etc).

Should I unit test a class for having MEF attributes?

I want to refactor a DLL to make it MEFable too. Should I unit test whether a class is decorated with [Export] or [Import] and other MEF attributes?
Your tests should focus more on the goal instead of the mechanism. Create tests that verify things like "if I throw types X, Y and Z together in a container, then I can pull an IFoo interface from the container", like this:
[Test]
public void Can_get_IFoo_from_container_with_Foo_Bar_Baz()
{
var catalog = new TypeCatalog(typeof(Foo), typeof(Bar), typeof(Baz));
using (var container = new CompositionContainer(catalog))
{
var test = container.GetExportedValue<IFoo>();
}
}
This is no longer a real "unit" test because it involves multiple classes and an IoC container. We just call them "composition tests".
After thinking some hours and reading some TDD blogs again I should say, YES, I have to test whether my class has MEF attributes or not.
So before refactoring my classes I write unit tests in that way:
[TestClass]
public class When_SampleClass_mefable
{
[TestMethod]
[TestCategory("LFF.Kabu.Win.Login.ViewModel.SampleClass")]
public void Should_SampleClass_be_marked_with_Export_Attibute()
{
//arrange
var info = (typeof (SampleClass));
//act
var attr = info.GetCustomAttributes(true);
var hasExportAttribute =
attr.Where(x => x.GetType() == typeof (ExportAttribute))
.Where(x => ((ExportAttribute)x).ContractType == typeof(SampleClass))
.Count() > 0;
//assert
Assert.IsTrue(hasExportAttribute, "SampleClass is not marked with Export.");
}
}
For other MEF attributes like [ImportingConstructor] or [PartCreationPolicy] I do it the same way.