.net – Moq.Of setup for Action with a callback and capturing method parameter


Lets say we have the following interface:

public interface IGetRandomString
{
    void Init();
    bool IsInited { get; }
    //returns random string of length chars
    string GetRandomString(int length);
}

and a mock for it described in a classic way:

public void GetRandomStringTest()
{
    private bool initialized;
    private Random random = new Random();
    private string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+-._";

    private Mock<IGetRandomString> mock;
    private IGetRandomString mockedInterface;
    //mock setup
    mock = new Mock<IGetRandomString>();
    mockedInterface = mock.Object;
    mock.Setup(d => d.Init()).Callback(() => initialized = true);
    mock.Setup(d => d.IsInited).Returns(() => initialized);
    mock.Setup(d => d.GetString(It.IsAny<int>())).Returns<int>(length => initialized ? GetRandomString(length) : string.Empty);
    //unit test
    const int length = 10;
    mockedInterface.Init();
    var isInited = mockedInterface.IsInited;
    var ret = mockedInterface.GetString(length);
    Assert.That(ret.Length == length);
}

private string GetRandomString(int length) => new string(Enumerable.Repeat(chars, length).Select(s => s[random.Next(s.Length)]).ToArray());

How to get the same setup with modern Mock.Of<T> syntax?

...
mockedInterface = Mock.Of<IGetRandomString>(m =>
    //property setup is ok
    m.IsInited == initialized &&
    //how to setup action method and it's callback?
    m.Init() &&
    //how to capture length method parameter?
    m.GetString(It.IsAny<int>()) == (initialized ? GetRandomString(length) : string.Empty));
mock = Mock.Get(IGetRandomString);
...

Leave a Reply

Your email address will not be published. Required fields are marked *