Mocking Delegates with Moq

I have an interface:

public interface IRepeater
{
    void Each(string path, Action<string> action);
}

I want to mock this interface using Moq. Now I can obviously do the following:

var mock = new Mock<IRepeater>();
mock.Setup(m => m.Each(It.IsAny<string>(), It.IsAny<Action<string>>());

However, to help testing, I want to be able to mock stringthat which is passed in Action<string>. Can this be done with Moq? If so, how?

Update

To clarify, I'm testing another classthat has a dependency on IRepeater. I want to make fun IRepeater.Eachso that I can control stringwhich one gets Action, so I can check the behavior.

example

So, if I have class, like that.

public class Service
{
    private readonly IRepeater _repeater;

    public Service(IRepeater repeater)
    {
        _repeater = repeater;
    }

    public string Parse(string path)
    {
        var builder = new StringBuilder();

        _repeater.Each(path, line => builder.Append(line));

        return builder.ToString();
    }
}

How can I make fun IRepeater.Eachso I can test Service.Parse?

+4
2

callback. line => builder.Append(line) , :

    [TestMethod]
    public void Test_Service_When_Passing_String_And_ActionDelegate()
    {
        var fakeReporter = new Mock<IRepeater>();

        fakeReporter.Setup(x => x.Each(It.IsAny<string>(), It.IsAny<Action<string>>()))
            .Callback<string, Action<string>>((s, action) => action(s));

        var target = new Service(fakeReporter.Object);

        var result = target.Parse("asdfghj");

        Assert.AreEqual("asdfghj", result);
    }

, , , :

     [TestMethod]
    public void Test_Service_When_Passing_String_And_ActionDelegate()
    {
        var fakeReporter = new Mock<IRepeater>();

        fakeReporter.Setup(x => x.Each(It.IsAny<string>(), It.IsAny<Action<string>>()))
            .Callback<string, Action<string>>((s, action) =>
            {
                Assert.AreEqual("asdfghj", s);
                foreach (var w in "pass")
                {
                    action(w.ToString());
                }
            });

        var target = new Service(fakeReporter.Object);

        var result = target.Parse("asdfghj");

        Assert.AreEqual("pass", result);
    }

BTW It.IsAny<string>() , Assert.AreEqual("asdfghj", s); ( ...)

+6

, , () IRepeater. , (The Repeater - , ).

:

public class Service
{
    private readonly IRepeater repeater;

    public Service(IRepeater repeater)
    {
        this.repeater = repeater;
    }

    public void Foo(string str, Action<string> action)
    {
        repeater.Each(str, action);
    }
}

public class ActionImplement
{
    public virtual void Action(string str)
    {
        Console.Write(str);
    }
}

public interface IRepeater
{
    void Each(string path, Action<string> action);
}

ActionImplement.Action

    [TestMethod]
    public void Test_Service_When_Passing_String_And_ActionDelegate()
    {
        var actionImplement = new Mock<ActionImplement>();
        actionImplement.Setup(m => m.Action(It.IsAny<string>()));

        var mock = new Mock<IRepeater>();
        mock.Setup(m => m.Each(It.IsAny<string>(), actionImplement.Object.Action));


        var srv = new Service(mock.Object);
        srv.Foo("aa",actionImplement.Object.Action);


        mock.Verify(ai => ai.Each("aa", actionImplement.Object.Action));


    }
0

Source: https://habr.com/ru/post/1620956/


All Articles