鉴于此课程:
public class MyClass
{
private void MyMethod()
{
//...
}
public void Execute()
{
try
{
//...
MyMethod();
//...
}
catch(Exception e)
{
...
}
}
}
我如何模拟MyMethod抛出OutOfmemoryException
?
编辑1:
鉴于MyMethod
从数据库加载某些数据的下一种情况,并且发生了一些不可预测的错误,MyMethod
将引发异常。我希望能够对这种情况进行单元测试。在我的例子中,execute方法的catch子句。
答案 0 :(得分:6)
我不使用Moq,所以可能你可以用某种方式做到这一点 - 但是我认为如果你需要,你就是做嘲弄错误。
您通常应该嘲笑依赖 - 并且您不能依赖于您尝试测试的类中的私有成员,是吗?通常我会模拟一个界面 - 偶尔它可以用来模拟一个类,但我通常不会。如果您正在调用某个依赖项并且希望该调用的结果为OutOfMemoryException
,那么只需使该 public 调用抛出该异常。
如果您觉得自己有充分的理由想要模仿私有方法,请提供有关您的背景的更多详细信息。
答案 1 :(得分:3)
您只能模拟公共属性和公共方法(无论是在接口中还是在类中直接定义)。
答案 2 :(得分:-1)
你遇到的基本上是对模仿的原始模式的限制。
有一些商业框架可以解决这个问题 - 来自Telerik的JustMock是最合理的价格。他们通过将自己作为分析器附加并替换执行的字节码来工作 - 所以他们真的使用方法。
MOCK - 以及所有其他人通过基本的子类化/实现来完成工作 - 你不能将私有或非虚方法子类化。这使得它们无法模拟任何不应该是子类的正确定义的密封对象 - 你必须将对象打开,然后允许各种可能的滥用。
他们也不能模仿静态方法 - 少数人可以。这非常有用,因为它允许您例如模拟对DateTime.UtcNow的调用,因此它总是返回SPECIFIC时间,这可能在单元测试中需要。
所以,对不起,Mock无法做到这一点。
答案 3 :(得分:-1)
我没有机会尝试这个,但我们在工作的地方使用Moq,我也一直在努力解决这类问题。 首先,Moq不是基于公共,私人等本身。它基于您的测试类可见的内容。我们在VB.net上做了很多工作,所以我最近的记忆就是那个(即带上一粒盐)。 1)为了测试“私有”方法 - 尝试让测试程序集可以看到包含被测试类的程序集。 Look here有关如何执行此操作的信息。您需要将它们更改为“内部”(与vb.net中的朋友相同)。在经典TDD中,您(通常)会尝试将您测试的类中的所有内容都置于测试本身。 2)一旦你可以看到MyMethod,你应该能够模拟出你需要的任何异常的响应(假设你可以实例化并抛出它)。 3)其他想法是在测试代码中创建一个内部类,扩展被测试的类并覆盖您想要从测试类中控制的方法。
有时候,特别是对于遗留代码,你必须做一些丑陋的事情来使代码可以测试。