我想模拟一个类的特定方法,我面临的问题是模拟的是该类没有任何接口,并且该方法也不是虚拟的。
任何人都可以建议任何其他方式来实施模拟。
任何帮助将不胜感激。 提前致谢
答案 0 :(得分:6)
选项1:TypeMock Isolator或类似的东西,它允许比正常的模拟更深入地搞乱代码。
选项2 :(如果可能,首选)改变设计,例如通过引入一个接口并创建一个委托实现,它只调用现有的测试不友好类。然后,您可以依赖于接口,在测试中模拟它,并委托“实际”实现进行生产。
这是假设你真的应该嘲笑这个班级,当然。你不应该自动模拟你的代码使用的所有 - 我倾向于考虑模仿某些描述的“服务”,而我不会嘲笑(例如)List<T>
。
答案 1 :(得分:3)
有一些单元测试框架,例如TypeMock Isolator,允许您模拟非虚拟成员。
答案 2 :(得分:3)
我建议重构你的代码;)所有通过派生模拟类创建mock的模拟框架都需要方法是虚拟的(这是更多的CLR要求而不是模拟框架)。
要模拟非虚拟方法,您可以使用基于探测器的框架,如Moles或TypeMock Isolator,但是这需要使用特殊的运行器来运行测试运行器,这将使CLR探查器连接到进程
答案 3 :(得分:1)
要纯粹嘲笑遗留类,我会做以下事情:
创建一个包含我打算使用的ONLY公共成员的接口。 例如。
public interface IDbContext {
int SaveChanges();
}
如果目标遗留类是密封的,那么我将创建一个代理/装饰器类,它实现新接口并调用底层方法/属性。
public class MyDbContextProxy : IDbContext {
DbContext _context = null;
public MyDbContextProxy(DbContext interceptedContext) {
_context = interceptedContext;
}
// decorated method
public int SaveChanges() {
_context.SaveChanges();
}
}
如果目标遗留类未被密封,我将创建目标的后代并实现该接口。类auto遵守界面。
public class MyDbContextProxy : DbContext, IDbContext {
// child adheres to interface by inheritence
}
现在你可以模拟掉IDbContext。
答案 4 :(得分:1)
目前在VS2012中有类似Fakes Framework的东西。它是Moles的继承者(也能够像TypeMock一样模拟类等)。它仅在Ultimate版本中可用,所以我不认为它值得Ultimate的价格。
但是,我想从其他角度讨论模拟类的问题。
这是一个很好的方法来模拟类而不是接口,或者它是一种难闻的气味?我从来没有使用过TypeMock(在小公司里考虑它太贵了),但人们声称它有点“太强大”所以我想使用Moq / RhinoMocks,但有时候我想模仿/伪造一种方法,留下其他方法。在测试过程中,考虑模拟/伪造方法是我的坏方法吗?或有时需要它?