【发布时间】:2019-05-22 06:59:05
【问题描述】:
我正在使用 Moq 模拟一些实现,我想验证在此接口上正确调用了一个方法,问题是它看起来像这样:
public interface IToBeMocked {
void DoThing(IParameter parameter);
}
public interface IParameter {
Task<string> Content { get; }
}
所以我设置了我的模拟:
var parameter = "ABC";
var mock = new Mock<IToBeMocked>();
mock
.Setup(m => m.DoThing(It.IsAny<IParameter>()))
.Callback<IParameter>(p async => (await p.Content).Should().Be(parameter));
new Processor(mock.Object).Process(parameter);
mock
.Verify(m => m.DoThing(It.IsAny<IParameter>()), Times.Once);
不幸的是,这个测试已经通过以下实现:
public class Processor {
public Processor(IToBeMocked toBeMocked){
_toBeMocked = toBeMocked;
}
public void Process(string parameter){
_toBeMocked.DoThing(null);
}
}
因为 Callback 是异步的,但签名需要一个 Action,这意味着从不等待等待者,并且测试在抛出异常之前结束。
Moq 中是否有任何等待异步回调的功能?
编辑
似乎有些混乱。我希望这可以澄清问题。
我正在做 TDD。我已经实现了最简单的代码外壳来编译测试。然后我编写了测试以确保“ABC”是Task 的结果,并且我已经设置了测试运行。它正在过去。 这是问题。我希望测试失败,所以我可以实现“真正的”实现。
编辑 2
我越想越觉得这可能是不可能的。我已经为回购打开了一个问题:https://github.com/moq/moq4/issues/737 但我正在考虑实现这样一个功能,因为我正在编写请求以期待提交 PR,这似乎是不可能的。不过,如果有人有任何想法,我很乐意在这里或在 GitHub 问题中听到他们的意见,我会及时更新这两个地方。现在,我想我将不得不使用存根。
【问题讨论】:
-
在提供的示例中有些事情没有加起来。为什么要回调?你到底想测试什么?
Processor的实现看起来也不正确。 -
@Nkosi 谢谢,是的,我错过了方法调用。尝试测试以确保通过参数将“ABC”字符串传递给我的模拟,不幸的是,公开公开字符串的唯一方法是通过任务。
-
但您将
null传递给DoThing。为什么? -
@Nkosi 因为在 TDD 中,您会做最简单的事情来让它通过并编写测试来强制执行正确的实现。我的测试通过了,即使我的实现“明显错误”。
-
它正在通过,因为安排的行为将按配置工作。该回调对测试没有影响,因为它在另一个线程上