samedi 16 mars 2019

Mocking Func

I have some use cases where I pass Funcs to some methods. What I'm trying to do is create an extension or helper with Moq that allows my tests to easily create functions. The goal of this helper is

  1. Easy to define a function with an expected input and a fixed output
  2. Test should fail if function is not invoked
  3. Test should fail if function is invoked with wrong input
  4. Using It.IsAny<TInput>() should work as in any mock

I got most of what I wanted, but item 4 is eluding me. Here's the extension and tests with the elusive failing test I don't understand

public static Func<TIn, TOut> FixedFunc<TIn, TOut>(this MockRepository repo, TIn expectedInput, TOut fixedOutput)
{
    var verifier = repo.Create<IInvokable<TIn, TOut>>(MockBehavior.Strict);

    verifier.Setup(m => m.Invoke(expectedInput))
        .Returns(fixedOutput);

    return input => verifier.Object.Invoke(input);
}

public static Func<TIn, TOut> FixedFunc<TIn, TOut>(this MockRepository repo, TOut fixedOutput)
{
    var verifier = repo.Create<IInvokable<TIn, TOut>>(MockBehavior.Strict);

    verifier.Setup(m => m.Invoke(It.IsAny<TIn>()))
        .Returns(fixedOutput);

    return input => verifier.Object.Invoke(input);
}

public interface IInvokable<TIn, TOut>
{
    TOut Invoke(TIn input);
}

and here the tests

[Fact] // succeeds
public void MockFunc_SameObject_RetursResult()
{
    var expectedInput= new object();
    var expectedOutput = 2;

    var repo = new MockRepository(MockBehavior.Strict);
    var function = repo.FixedFunc(exptecedInput, expectedOutput);

    var output = function(expectedInput);
    Assert.Equal(expectedOutput, output);

    repo.VerifyAll();
}

[Fact]
// Fails with the following exception:
// "Moq.MockException: IInvokable`2.Invoke(object) invocation failed with mock behavior Strict.
// All invocations on the mock must have a corresponding setup."
public void MockFunc_IsAny_RetursResult()
{
    var exptecedInput = new object();
    var expectedOutput = 2;

    var repo = new MockRepository(MockBehavior.Strict);
    var function = repo.FixedFunc(It.IsAny<object>(), expectedOutput);

    var output = function(exptecedInput);
    Assert.Equal(expectedOutput, output);

    repo.VerifyAll();
}

[Fact] // succeeds
public void MockFunc_WithAny_RetursResult()
{
    var expectedOutput = 2;

    var repo = new MockRepository(MockBehavior.Strict);
    var function = repo.FixedFunc<object, int>(expectedOutput);

    var output = function(new object());
    Assert.Equal(expectedOutput, output);

    repo.VerifyAll();
}

I don't understand how using It.IsAny works for FixedFunc<TOut> but not for FixedFunc<TIn, TOut>

Aucun commentaire:

Enregistrer un commentaire