Why does using an non-inlined It.IsAny<t> in Moq not work correctly?

时间:2015-11-12 10:49:03

标签: c# moq

Assigning It.IsAny<T>() to a variable for use in a Setup on a mocked object does not work as expected: the test shown below fails.

However, if I inline the anyString variable the test passes. What's going on here?

public class MyService
{
    private readonly IDependency _dependency;

    public MyService(IDependency dependency)
    {
        _dependency = dependency;
    }

    public string UseTheDependency(string input)
    {
        return _dependency.GetValue(input);
    }
}

public interface IDependency
{
    string GetValue(string input);
}

public class Tests
{
    [Test]
    public void TestTheTestClass()
    {
        var mockDependency = new Mock<IDependency>();
        var anyString = It.IsAny<string>();
        mockDependency.Setup(x => x.GetValue(anyString)).Returns("expected value");
        var service = new MyService(mockDependency.Object);
        var result = service.UseTheDependency("something random");
        Assert.That(result, Is.EqualTo("expected value"));
    }
}

1 个答案:

答案 0 :(得分:2)

This is because the Setup method takes a Linq Expression (Expression<Func<IDependency, string>>) as a parameter, not a delegate (Func<IDependency, string>). It allows Moq to inspect the abstract syntax tree to know what call is being configured. If you use a variable declared outside the expression, Moq doesn't know that you used It.IsAny, it just sees a null (technically, it sees an access to the field anyString of the object that encapsulates the captured local variables, and that field just contains null).