Mocking constructor dependencies using AutoMoq attribute - c#

I'm wondering if there is a way of setting up a mock for a dependency before the constructor of the System Under Test (SUT) is called when using a test case that sets up AutoData.
My SUT looks like:
class Sut
{
private readonly IFoo foo;
public Sut(IFooFactory factory)
{
this.foo = factory.Build(1, 2);
}
public IFoo Foo
{
get
{
return this.foo;
}
}
}
So the test that I'm writing looks like:
[Theory]
[AutoData]
internal void Foo_IsCorrectlySet_Test(
[Frozen] Mock<IFooFactory> fooFactory,
IFoo foo,
Sut sut)
{
fooFactory.Setup(mock => mock.Build(1, 2))
.Returns(foo)
.Verifiable();
var actual = sut.Foo;
Assert.Equal(foo, sut);
fooFactory.Verify();
}
Obviously this test fails as the constructor to the Sut runs before I am able to setup the IFooFactory. So I thought that I may have been able to change the declaration of the Sut to Lazy<Sut> in the test.
But again the constructor is still run before the actual test code is run meaning that my test is going to fail.
Now I know that I could easily setup this test with an actual Fixture object and create all of my objects manually and setting them up before I call to create the Sut which is fine but I'm wanting to keep my tests all roughly the same therefore I'm wondering if there is a way that I could still setup my test with the AutoData attribute but not run the constructor until after everything is setup?

AutoFixture was originally build as a tool for Test-Driven Development (TDD), and TDD is all about feedback. In the spirit of GOOS, you should listen to your tests. If the tests are hard to write, you should consider your API design. AutoFixture tends to amplify that sort of feedback, which may also be the case here.
Consider the invariants of the Sut class. Since it has a read-only IFoo class field, I'd interpret this as a strong indication that IFoo is a dependency of the class.
If that's the case, then inject IFoo via the constructor, instead of IFooFactory:
public class Sut
{
private readonly IFoo foo;
public Sut(IFoo foo)
{
this.foo = foo;
}
public IFoo Foo
{
get { return this.foo; }
}
}
You can still compose it using IFooFactory in the application's Composition Root:
var sut = new Sut(aFactory.Build(1, 2));
This will make the tests easier to write. I can't even show you how the above test would look with this refactoring, because it'd be redundant and can (and should) be deleted.
FWIW, the original design proposed above violates Nikola Malovic's 4th law of IoC that constructors should do no work.

You can use the Fixture object pattern.
This allows you to setup your mocks before creating the sut.
Something in the lines of:
private class Fixture
{
public Mock<FooFactory> FooFactoryMock { get; set; } = new Mock<FooFactory>();
public Sut GetSut()
{
return new Sut(FooFactoryMock.Object);
}
}
[Theory]
[AutoData]
internal void Foo_IsCorrectlySet_Test(
IFoo foo)
{
var fixture = new Fixture();
fixture.FooFactory.Setup(mock => mock.Build(1, 2))
.Returns(foo)
.Verifiable();
var sut = fixture.GetSut();
var actual = sut.Foo;
Assert.Equal(foo, sut);
fooFactory.Verify();
}

You can use [Frozen] Attribute to freeze Moq dependency or try out write your own [CustomAttribute] to control dependencies.

Related

How do I setup MOQ to Set property Objects and verify the method [duplicate]

It is my understanding that I can test that a method call will occur if I call a higher level method, i.e.:
public abstract class SomeClass()
{
public void SomeMehod()
{
SomeOtherMethod();
}
internal abstract void SomeOtherMethod();
}
I want to test that if I call SomeMethod() then I expect that SomeOtherMethod() will be called.
Am I right in thinking this sort of test is available in a mocking framework?
You can see if a method in something you have mocked has been called by using Verify, e.g.:
static void Main(string[] args)
{
Mock<ITest> mock = new Mock<ITest>();
ClassBeingTested testedClass = new ClassBeingTested();
testedClass.WorkMethod(mock.Object);
mock.Verify(m => m.MethodToCheckIfCalled());
}
class ClassBeingTested
{
public void WorkMethod(ITest test)
{
//test.MethodToCheckIfCalled();
}
}
public interface ITest
{
void MethodToCheckIfCalled();
}
If the line is left commented it will throw a MockException when you call Verify. If it is uncommented it will pass.
No, mock testing assumes you are using certain testable design patterns, one of which is injection. In your case you would be testing SomeClass.SomeMethod and SomeOtherMethod must be implemented in another entity which needs to be interfaced.
Your Someclass constructor would look like New(ISomeOtherClass). Then you would mock the ISomeOtherClass and set expectation on its SomeOtherMethod to be called and verify the expectation.
Even though I agree that the #Paul's answer is the recommended way to go I just want to add one alternative way which is provided by moq off the self.
Since SomeClass is abstract it is indeed mockable, but public void SomeMehod() isn't. The point is to find the way to mock and somehow invoke that method and then using CallBase propagate the call to the SomeOtherMethod(). It might sound as a hack but it is simple in essence. It could be used in the case if the proposed refactoring is not possible.
// This class is used only for test and purpose is make SomeMethod mockable
public abstract class DummyClass : SomeClass
{
public virtual void DummyMethod() => base.SomeMethod();
}
Then you could setup DummyMethod() to propagate the call by setting CallBase flag.
//Arrange
var mock = new Mock<DummyClass>();
mock.Setup(m => m.DummyMethod()).CallBase();
//Act
mock.Object.SomeMethod();
//Assert
mock.Verify(m => m.SomeOtherMethod(), Times.Once);

Implement Moq Unit Test and Actual Unit Test methods in same class

Need to implement Moq Unit Test and Actual Unit Test in same test class , with help of some config file key.
Is it possible to do so using same object which will be assigned based on the config value ?
Means if config file key is "Moq" then Moq Unit Test will run and if not Actual Unit Test will run in same test class and in same method .
Yes you can, but likely it's not the best practice.
For example,
public class MyClass
{
IDependency _d;
public MyClass(IDependency d)
{
_d = d;
}
}
public class Dependency : IDependency
{
}
In the test class, I can have something like this:
[TestClass]
public class MyClassTests
{
MyClass _sut;
Mock<IDependency> _mockDependency;
Dependency _realDependency;
[TestInit]
public void Init()
{
var shouldUseMock = ConfigurationManager.AppSettings["key"];
if(shouldUseMock)
{
_mockDependency = new Mock<IDependency>();
_sut = new MyClass(_mockDependency.Object)
}
else
{
_realDependency = new Dependency();
_sut = new MyClass(_realDependency);
}
}
}
The problem will be setting up expectations based on different situations and it makes the test class much harder to maintain. You should rather create two tests, one real unit test with the mock and the other kind of integration test with real implementation.

How to add a specific implementation of a Mock created with Autofixture?

I am writing tests for class (lets call it Sut) which has some dependencies injected via constructors. For this class I have to use the constructor with the most parameters, therefore I used the AutoMoqDataAttributeGreedy implementation:
public class AutoMoqDataAttribute : AutoDataAttribute
{
public AutoMoqDataAttribute() : base(new Fixture().Customize(new AutoMoqCustomization()))
{
}
}
public class AutoMoqDataAttributeGreedy : AutoDataAttribute
{
public AutoMoqDataAttributeGreedy() : base(new Fixture(new GreedyEngineParts()).Customize(new AutoMoqCustomization()))
{
}
}
The constructor of my sut looks like this:
public class Sut(IInerface1 interface1, IInterface2 interface2, IInterface3 interface3)
{
Interface1 = interface1;
Interface2 = interface2;
Interface3 = interface3;
}
One example test looks like this:
[Theory, AutoMoqDataAttributeGreedy]
public void SomeTest([Frozen]Mock<IInterface1> mock1 ,
Mock<IInterface2> mock2,
Sut sut,
SomOtherdata data)
{
// mock1 and mock2 Setup omitted
// I want to avoid following line
sut.AddSpeficicInterfaceImplementation(new IInterface3TestImplementation());
sut.MethodIWantToTest();
//Assert omitted
}
The problem is that I need a specific implementation of IInterface3 for testing and I want to avoid adding a method to my SUT (Interface3TestImplementation) only for my unit test and I also I want to avoid repeating code since I have to add this instance in each and every test.
Is there a nice and neat way to have this implementation being added for all my test / for specific tests with Autofixture?
If you need to do this as a one-off test, then the answer by Enrico Campidoglio is the way to go.
If you need this as a general rule throughout all of your unit tests, you can customize the Fixture with a TypeRelay:
fixture.Customizations.Add(
new TypeRelay(
typeof(IInterface3),
typeof(IInterface3TestImplementation));
This will change fixture so that, whenever IInterface3 is needed, an instance of IInterface3TestImplementation will be created and used.
Using your IFixture that you have created, you can call .Register against a specific interface and supply the object to use when that interface is then subsequently used.
e.g.
_fixture = new Fixture().Customize(new AutoMoqCustomization());
_fixture.Register<Interface3>(() => yourConcreteImplementation);
You could also use mocking that would allow you to then use .Freeze on the fixture and that way you could just set some expected calls against the interface and wouldn't need a completely concrete instance. You could let AutoFixture create a default implementation for you and apply the setup that you configured.
e.g.
var mockedInterface = _fixture.Freeze<Mock<Interface3>>();
mockedInterface
.Setup(x => x.PropertyOnInterface)
.Returns("some value");
You can have AutoFixture create an instance of a concrete type and tell it to use that instance every time it has to provide a value for any of its implemented interfaces. Here's an example:
[Theory, AutoMoqDataAttributeGreedy]
public void SomeTest(
[Frozen]Mock<IInterface1> mock1,
[Frozen]Mock<IInterface2> mock2,
[Frozen(Matching.ImplementedInterfaces)]IInterface3TestImplementation impl3,
Sut sut)
{
}
In this case, AutoFixture is going to create an instance of IInterface3TestImplementation and use it every time it encounters an interface implemented by that type.
This means that if the constructor of Sut has a parameter of type IInterface3, AutoFixture is going to pass it the the same instance that's being assigned to the impl3 parameter, which you can use in your test.
As an aside, there are other ways of matching frozen instances to types and members other than just by interface. If you want to know more, take a look at the members of the Matching enumeration.

How to unit test delegate was received in base class method?

I currently have a base service class that all my services extend. This is what one of the methods look like:
protected internal virtual T PerformServiceOperationWithExceptionHandling<T>(Func<T> func)
{
try
{
return func.Invoke();
}
...
}
In the derived classes I call the method like this:
public AddGuestResponse AddGuest(AddGuestRequest addGuestRequest)
{
return PerformServiceOperationWithExceptionHandling(() => AddGuestLogic(addGuestRequest));
}
I want to test AddGuest and ensure "AddGuestLogic" is being passed as a parameter in the base method? How do I achieve this with nSubstitute and nUnit. I don't think its possible?
================================================
I ended up using the following code:
[Test]
public void AddGuest_WhenCalled_PerformsAddGuestLogicWithExceptionHandling()
{
Func<AddGuestResponse> addGuestLogic = null;
_guestService.PerformServiceOperationWithExceptionHandling(Arg.Do<Func<AddGuestResponse>>(arg => addGuestLogic = arg));
var addGuestRequest = new AddGuestRequest();
_guestService.AddGuest(addGuestRequest);
_guestService.ClearReceivedCalls();
addGuestLogic.Invoke();
_guestService.Received().AddGuestLogic(addGuestRequest);
}
The _guestService is created in my setup method as follows: Substitute.ForPartsOf();
I second Sunny Milenov's answer, but would go one step further by advising you to change your design. I have learned the hard way that many of these headaches with testing base class behavior go away when you follow the principle of composition over inheritance.
I.e., if you refactor your base class to a collaborator, which you inject into your services' constructor, you can test that in isolation and mock it in your services' tests. No worrying about testing an abstract base class or testing the same exception handling in all of your services' tests.
You would test that the collaborator correctly invokes the func in the collaborator's tests.
In the services' tests you can just mock the collaborator to return the Func's result right away:
[Test]
public void ServiceLogicIsExecuted()
{
var collaborator = Substitute.For<ICollaborator>();
//Tell the test double to return the Func's result. You'd probably want to do this in the setup method.
collaborator.PerformServiceOperation(Arg.Any<Func<int>>()).Returns(x => ((Func<int>)x[0]).Invoke());
var sut = new Service(collaborator);
var result = sut.CalculateSomething();
Assert.That(result, Is.EqualTo(99));
}
public class Service
{
private readonly ICollaborator _collaborator;
public Service(ICollaborator collaborator)
{
_collaborator = collaborator;
}
public int CalculateSomething()
{
return _collaborator.PerformServiceOperation(ExecuteLogic);
}
private static int ExecuteLogic()
{
return 99;
}
}
public interface ICollaborator
{
T PerformServiceOperation<T>(Func<T> func);
}
Short answer - you shouldn't. Unit testing is about testing the behavior of the tested method, not the implementation details.
Long answer:
It doesn't matter how the class internally works, as far as it produces the expected results.
You need to test your public method on the final class and see if this works as expected. Testing a base/abstract class in isolation proves nothing.

Are my NUnit tests actually running correctly?

I'm trying to be a good developer and actually right some unit tests for some code I have written.
I am using NUnit with Ninject.MockingKernel.Moq and followed the documentation on https://github.com/ninject/ninject.mockingkernel/wiki/Examples. Here is an example of what I have been working with
[TestFixture]
public class MyUnitTest
{
private readonly MoqMockingKernel _kernel;
public MyUnitTest()
{
_kernel = new MoqMockingKernel();
}
[SetUp]
public void SetUp()
{
_kernel.Reset(); // Not really sure why this is included (something to do with caching...)
}
[Test]
public void MyTest()
{
var moqService = _kernel.GetMock<IMyService>();
moqService.Setup(x=>x.MyMethod("With parameter")
.Returns(new MyObject {Id = 1, Name = "With parameter"});
var service = _kernel.Get<IMyService>();
service.MyMethod("With parameter");
moqService.VerifyAll();
}
}
Now, to my amazement this actually works but is it actually testing the logic in the code? Or is it saying when you return this method this is what will be returned?
I did a small test, MyMethod returns an object:
var method = service.MyMothod("With parameter");
Debugged the test and method.Id does in fact equal 1 so I'm 75% certain it's working but I thought it best to check with someone more knowledgeable than myself!
If your goal is to test a IMyService that you implemented elsewhere, you are doing it wrong. What you are doing is creating a mock IMyService and testing that it is correctly mocked, which achieves not much.
You should use kernel.GetMock() if you need an IFoo to test your IMyService because your implementation of IMyService takes a IFoo as a parameter of its constructor (like it is done in the example that you linked).

Categories

Resources