Moq.执行作为参数给定的Action

26

如何模拟以下方法:

public class TimeService : ITimeService
{
    public void SetDelyEvent(int interval, bool reset,  Action action)
    {
        var timer = new Timer {Interval = interval, AutoReset = reset};
        timer.Elapsed += (sender, args) => action();
        timer.Start();
    }
}
我想调用给定的 ACTION。
var stub = new Mock<ITimeService>();
stub .Setup(m => m.SetDelyEvent(100, false, ACTION));

你是希望在函数调用只执行一次时立即执行传入的Action,还是试图“重新创建”Moq内部的TimeService行为? - Scott Chamberlain
我想立即调用一次Action。这个Action是我系统下测试单元中的一个私有方法,必须调用它才能生成结果。 - Miroslav Popov
1个回答

40

只需使用.Callback(方法来调用一个方法,当您的模拟执行时将运行该方法,您的回调函数可以通过传递给原始方法的Action进行传递,您需要做的就是在回调中执行Action。

    var stub = new Mock<ITimeService>();
    stub .Setup(m => m.SetDelyEvent(It.IsAny<int>(), It.IsAny<bool>(), It.IsAny<Action>()))
         .Callback((int interval, bool reset, Action action) => action());

非常好。只有那个操作必须是 It.IsAny<Action>() - Miroslav Popov
没问题,这不会影响解决方案,我只是用“ACTION”是因为我以为那是你声明的变量。代码使用m.SetDelyEvent(It.IsAny<int>(), It.IsAny<bool>(), It.IsAny<Action>())同样可以工作,你仍然可以使用相同的回调函数。 - Scott Chamberlain
@MiroslavPopov 我已经更新了代码,使用了任意属性而不是你在原始示例中使用的定义属性。 - Scott Chamberlain
这对我也很有效。值得注意的是,这也适用于依赖注入服务,例如Autofac。 - Mike Upjohn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接