我有一个界面:
public interface IRepeater { void Each(string path, Actionaction); }
我想用这个模拟这个界面Moq
.现在我可以做到以下几点:
var mock = new Mock(); mock.Setup(m => m.Each(It.IsAny (), It.IsAny >());
但是,为了帮助测试,我希望能够模拟将string
其传递给Action
.可以这样做Moq
吗?如果有,怎么样?
澄清我正在测试class
一个依赖于它的不同的东西IRepeater
.我想嘲笑IRepeater.Each
,所以我可以控制string
的Action
得到,所以我可以测试的行为.
所以如果我有class
这样的话.
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(); } }
我如何模拟IRepeater.Each
以便我可以测试Service.Parse
?
你必须使用callback
方法.由于line => builder.Append(line)
是方法行为的一部分,因此在测试方法时必须执行此行为:
[TestMethod] public void Test_Service_When_Passing_String_And_ActionDelegate() { var fakeReporter = new Mock(); fakeReporter.Setup(x => x.Each(It.IsAny (), It.IsAny >())) .Callback >((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(); fakeReporter.Setup(x => x.Each(It.IsAny (), It.IsAny >())) .Callback >((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); }
顺便说一下你可以用It.IsAny
字符串替换掉然后删除Assert.AreEqual("asdfghj", s);
(我只是想以明确的方式测试事物......)