我需要使用Moq测试以下方法。问题是switch语句中调用的每个方法都是私有的,包括最后的PublishMessage。但是这种方法(ProcessMessage)是公开的。我如何测试这个,以便我可以确保根据参数进行调用?请注意,我没有测试私有方法,我只想测试"调用"。我想模拟这些私有方法,并检查它们是否使用安装程序调用,但Moq不支持模拟私有方法。
public void ProcessMessage(DispenserMessageDataContract dispenserMessage)
{
var transOptions = new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted };
using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew, transOptions))
{
switch (dispenserMessage.Type)
{
case DispenserMessageType.AckNack:
UpdateAckNackMessageQueue(dispenserMessage);
break;
case DispenserMessageType.FillRequest:
CreateFillRequestMessageQueue(dispenserMessage);
break;
case DispenserMessageType.FillEvent:
UpdateFillEventMessageQueue(dispenserMessage);
break;
case DispenserMessageType.RequestInventory:
CreateRequestInventoryMessageQueue(dispenserMessage);
break;
case DispenserMessageType.ReceiveInventory:
CreateReceiveInventoryMessageQueue(dispenserMessage);
break;
}
scope.Complete();
}
PublishMessage(dispenserMessage);
}
答案 0 :(得分:10)
您必须将这些私有方法更改为至少受保护的虚拟对象,然后使用mock.Protected来模拟它们(http://blogs.clariusconsulting.net/kzu/mocking-protected-members-with-moq/)。你不能模仿私人方法。
Moq(以及其他一些框架)使用Castle Project的DynamicProxy在运行时动态生成代理,以便可以截获对象的成员而无需修改类的代码。该拦截只能在公共虚拟和受保护的虚拟方法上完成。
有关详情,请参阅以下网址: http://www.castleproject.org/projects/dynamicproxy/
答案 1 :(得分:3)
您可以在另一个类中提取私有方法并将其公开,然后使用Moq模拟那些并验证它们是否已被调用。
答案 2 :(得分:2)
Moq用于模拟接口中声明的属性和方法,以及类中的抽象属性和方法。
Moq测试背后的想法是测试您的被测试类与世界其他地方(其依赖项)之间的交互。 Moq通过创建接口的“模拟”实现或抽象类的派生来实现这一点。
Moq不能像私有方法那样覆盖现有的实现。这不是Moq的工作方式。
您应该使用所有可能的输入和预期输出测试“ProcessMessage”,或者您应该重构您的类以将调用委托给您可以使用Moq模拟的接口方法。无论如何,测试私有方法是一个坏概念。由于某种原因,它们被保密,这是为了隐藏实现,以便它可以随意改变。
答案 3 :(得分:0)
我更喜欢添加其他类(* Helper)并将所有私有方法移至public。然后,您可以直接轻松地测试您的方法。我没有找到更优雅的方式来做到这一点。
答案 4 :(得分:0)
在某些情况下,您可能需要在进行单元测试的类中更改私有方法的行为。您将需要模拟此私有方法,并使其返回特定情况所需的内容。由于此私有方法位于要测试的类中,因此对其进行模拟将更加具体。您必须使用间谍对象。
间谍对象 间谍是模拟框架可以访问的真实对象。尖顶对象是部分模拟的对象。他们的某些方法是真实的,有些是被嘲笑的。我要特别小心地使用间谍对象,因为您真的不知道其下发生了什么,以及您实际上是在测试类还是模拟版本。
public class PowerMockDemo
{
public Point callPrivateMethod() {
return privateMethod(new Point(1, 1));
}
private Point privateMethod(Point point) {
return new Point(point.getX() + 1, point.getY() + 1);
}
}
然后,您将模拟间谍对象
希望对您有帮助,
最美好的祝愿