Use mock.Provide() to Setup a delegate factory, used in the SUT constructor

2.5k views Asked by At

I am trying to test the behavior of a class, when it's passed one stub object via a delegate factory. I made a version of the test in which all the class's dependencies (except the factory) are passed as Mock objects and it works as supposed to. Now I am trying to use AutoMock to get the container to automatically create the mocks.

I am having issues passing concrete values for the delegate factory in the constructor in ClassUnderTest using mock.Provide(). (like this comment suggests)

Class that I am testing:

public ClassUnderTest
{
 private readonly firstField;
 private readonly Func<string, ISecondField, IThirdField, IResultField> resultFieldFactory;
 private int someCounter = -1;

 public ClassUnderTest(IFirstField firstField, Func<string, ISecondField, IThirdField, IResultField> resultFieldFactory )
 {
  this.firstField = firstField;
  this.resultFieldFactory= resultFieldFactory;
 }

 public methodToTest()
 {
  IResultField resultField = resultFieldFactory(someString, secondFieldValue, thirdFieldValue);
  resultField.AddToList();
 }
}

Business logic module :

public class BusinessLogicModule: Module
{
//some other things  that work

builder.RegisterType<ClassUnderTest>().As<IClassUnderTest>();
builder.RegisterType<SecondField>().As<ISecondField>();
builder.RegisterType<ThirdField>().As<IThirdField>();
builder.RegisterType<ResultField>().As<IResultField>();

}

Test class:

[TestClass]
public class TestClass()
{
 private IFirstField firstField;
 private Func<string, ISecondField, IThirdField, IResultField> funcToTriggerIResultFieldFactory;


 [TestInitialize]  
 public void Setup()
 {
  this.firstField= Resolve<IFirstField>();
  this.secondField= Resolve<ISecondField>();
  this.funcToTriggerIResultFieldFactory = Resolve<Func<string, ISecondField, IThirdField, IResultField>>();
 }


 [TestMethod]
 public void testMethodWithAutoMock()
 {
  using (var automock = AutoMock.GetLoose())
  {
    //trying to setup the SUT to get passed a "concrete" object
    autoMock.Provide(funcToTriggerIResultFieldFactory(stringValue, secondFieldValue, thirdFieldValue)); 

    var sut = autoMock.Create<IClassUnderTest>;

    sut.MethodToTest();
    //asserts
   }
 }

}

I would be grateful for any indication on what I am doing wrong. What am I missing? How could it be fixed? Is it a simple syntax fix or is something wrong with my approach to this test?

Thanks in advance for your time.

1

There are 1 answers

0
Matt Cole On

In your example, when you call autoMock.Provide() you are not passing in you factory function, but you are invoking the factory function and passing in the result (IResultField). To fix this, call

autoMock.Provide(funcToTriggerIResultFieldFactory);

Here is a full example of registering a function with the auto mocking container.