Rub*_*ink 76
难以击败https://github.com/Moq/moq4/wiki/Quickstart
如果这还不够清楚,我会称之为doc bug ...
编辑:回应你的澄清......
对于Setup您执行的每个模拟方法,您可以指出以下内容:
该.Callback机制说"我现在无法描述它,但是当这样的呼叫发生时,请给我回电话,我会做需要做的事情".作为同一个流畅的调用链的一部分,您可以控制结果通过.Returns" 返回(如果有的话)".在QS示例中,一个示例是它们使每次返回的值增加.
一般情况下,您不需要经常使用这样的机制(xUnit测试模式具有针对测试条件逻辑的反模式的术语),如果有任何更简单或内置的方法来确定您需要的内容,它应该是优先使用.
Justin Etheredge的Moq系列中的第3部分包含了它,并且还有另一个回调示例
Jef*_*all 51
下面是使用回调来测试发送到处理插入的数据服务的实体的示例.
var mock = new Mock<IDataService>();
DataEntity insertedEntity = null;
mock.Setup(x => x.Insert(It.IsAny<DataEntity>())).Returns(1)
.Callback((DataEntity de) => insertedEntity = de);
Run Code Online (Sandbox Code Playgroud)
替代通用方法语法:
mock.Setup(x => x.Insert(It.IsAny<DataEntity>())).Returns(1)
.Callback<DataEntity>(de => insertedEntity = de);
Run Code Online (Sandbox Code Playgroud)
然后你可以测试类似的东西
Assert.AreEqual("test", insertedEntity.Description, "Wrong Description");
Run Code Online (Sandbox Code Playgroud)
Callbackmoq中有两种类型.一个在呼叫返回之前发生; 另一个在调用返回后发生.
var message = "";
mock.Setup(foo => foo.Execute(arg1: "ping", arg2: "pong"))
.Callback((x, y) =>
{
message = "Rally on!";
Console.WriteLine($"args before returns {x} {y}");
})
.Returns(message) // Rally on!
.Callback((x, y) =>
{
message = "Rally over!";
Console.WriteLine("arg after returns {x} {y}");
});
Run Code Online (Sandbox Code Playgroud)
在两个回调中,我们可以:
Callback只是在调用模拟方法之一时执行所需的任何自定义代码的一种方法。这是一个简单的例子:
public interface IFoo
{
int Bar(bool b);
}
var mock = new Mock<IFoo>();
mock.Setup(mc => mc.Bar(It.IsAny<bool>()))
.Callback<bool>(b => Console.WriteLine("Bar called with: " + b))
.Returns(42);
var ret = mock.Object.Bar(true);
Console.WriteLine("Result: " + ret);
// output:
// Bar called with: True
// Result: 42
Run Code Online (Sandbox Code Playgroud)
我最近遇到了一个有趣的用例。假设您希望对模拟进行一些调用,但是它们同时发生。因此,您无法知道呼叫的顺序,但是您想知道发生了预期的呼叫(与顺序无关)。您可以执行以下操作:
var cq = new ConcurrentQueue<bool>();
mock.Setup(f => f.Bar(It.IsAny<bool>())).Callback<bool>(cq.Enqueue);
Parallel.Invoke(() => mock.Object.Bar(true), () => mock.Object.Bar(false));
Console.WriteLine("Invocations: " + String.Join(", ", cq));
// output:
// Invocations: True, False
Run Code Online (Sandbox Code Playgroud)
BTW不要被误导性的“之前Returns”和“之后Returns”区分所迷惑。这仅仅是您的自定义代码将在Returns评估之后还是之前运行的技术区别。在调用者眼中,两者都将在返回值之前运行。确实,如果该方法是void-returning ,则您甚至不能调用Returns它,但是它的作用相同。有关更多信息,请参见/sf/answers/2010896961/。