验证在单元测试中调用了一种方法或另一种方法
示例:
public bool Save(MyObj instance)
{
if (instance.IsNew)
{
this.repository.Create(instance);
}
else
{
this.repository.Update(instance);
}
}
如何在 Moq 中创建一个测试来验证:
- 是否正在读取
Create()
或属性
已被调用IsNew
Update()
Example:
public bool Save(MyObj instance)
{
if (instance.IsNew)
{
this.repository.Create(instance);
}
else
{
this.repository.Update(instance);
}
}
How do I create a test in Moq that verifies:
- that a property
IsNew
is being read - that either
Create()
orUpdate()
has been invoked
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我的头顶上浮现出:
验证是否正在读取
IsNew
属性:在上面的示例中,
IsNew
属性将返回true
,因此将采用 Create 路径。要验证是否调用了 Create 或 Update 方法,您需要对该功能进行一些挂钩。 看起来 Repository 是一个静态类,在这种情况下你不能用测试替身替换它,但我可能会以错误的方式读取你的代码......如果你可以用测试替身(模拟)替换它,您可以使用与上述相同的原则。
如果您可以在调用 Save 方法后检查存储库的状态,则可以通过基于状态的测试来判断遵循了哪两个代码路径。
如果两个代码路径的结果之间没有外部可观察的差异,那么最好不要测试这个特定的实现细节。 它可能会引导您走向一种称为 Overspecified Test 的反模式 - 您可以在优秀的书中阅读有关此反模式以及许多其他与单元测试相关的内容的更多信息 xUnit 测试模式。
编辑:
测试存储库可以用相同的方式完成:
对 Verulated 的调用是关键。 如果没有它,Moq 的默认行为就是让路,尽其所能,并且尽可能不抛出任何异常。
当您调用“可验证”时,您指示模拟期待该特定行为。 如果调用Verify时未满足该期望,它将抛出异常,从而导致测试失败。
Off the top of my head:
Verifying that the
IsNew
property is being read:In the example above, the
IsNew
property will returntrue
, so the Create path will be taken.To verify that either the Create or Update method was invoked, you need to have some hook into that functionality. It looks like Repository is a static class, in which case you can't replace it with a Test Double, but I may be reading your code in the wrong way... If you can replace it with a Test Double (Mock), you can use the same principle as outlined above.
If you can examine the state of your Repository after the Save method has been called, you may be able to tell by State-Based Testing which of the two code paths were followed.
If there's no externally observable difference between the result of the two code paths, it's probably a better idea not to test this specific implementation detail. It might lead you towards an anti-pattern called Overspecified Test - you can read more about this anti-pattern and many other unit test-related things in the excellent book xUnit Test Patterns.
Edit:
Testing the repositories can be done in the same way:
The call to Verifiable is the key. Without it, the default behavior of Moq is to get out of the way, do the best it can and not throw any exceptions if at all possible.
When you call Verifiable, you instruct the mock to expect that particular behavior. If that expectation has not been met when you call Verify, it will throw an exception, and thus fail the test.
不幸的是我自己有一个解决方案。
您所要做的就是将一个本地
int
变量设置为 0,然后模拟递增它。 最后你必须检查它的名称是否大于 0(或者恰好是 1,具体取决于问题)。会有两次测试。 一种将属性
IsNew
设置为true
,另一种将其设置为false
。Unfortunately I have a solution myself.
All you have to do is to have a local
int
variable that you set to 0 and then mocking increments it. In the end you have to check whether its name is more than 0 (or exactly 1, depending on the problem).There would be two tests. One that sets property
IsNew
totrue
and one that sets it tofalse
.