我正在为别人的代码编写单元测试,但我不允许修改这些代码。
假设我有:
class BadClass
{
public BadClass()
{
// the service isn't going to be running during testing
// it also has no interface
someFlag = AGloballyStoredService.getSomeFlag();
}
public bool someFlag;
}
由以下人员使用:
class AnotherBadClass
{
public AnotherBadClass(BadClass badClass)
{
someFlag = badClass.someFlag;
}
public bool someFlag;
}
说我想要测试:
public void AnotherBadClassConstructorTest()
{
BadClass badClass = new BadClass();
AnotherBadClass anotherBadClass = new AnotherBadClass(badClass);
Assert.IsNotNull(anotherBadClass);
}
我想模拟 BadClass,但它没有接口,并且如果服务未运行,它在构造函数期间会失败。
考虑到我无法修改正在测试的代码,是否有一种简单的方法可以使其工作?
如果归根结底,我可以告诉他们,他们要么让我修改现有的代码库,要么接受该模块低于 10% 的覆盖率。
考虑到我无法修改正在测试的代码,是否有一个
使这项工作有效的简单方法?
不。但是,我看到两个非直接的选择:
A) Use 微软假货 https://msdn.microsoft.com/en-us/library/hh549175.aspx通过重写库来提供模拟。您不必修改代码。示例:您可以修改静态日期时间.现在返回您选择的日期,如下所示:
System.Fakes.ShimDateTime.NowGet =
() =>
{ return new DateTime(fixedYear, 1, 1); };
B)您可以尝试继承被测试的类并覆盖使用的方法/构造函数。但有两个限制。您必须能够使用模拟对象实例化/交换测试类的实例(通过使用反射,您可以获取私有成员),并且模拟方法必须是虚拟的。在您的情况下,您将创建:
class BadClassMock : BadClass
{
public BadClassMock()
{
}
public bool someFlag;
public void InitForTest()
{
someFlag = true;
}
}
只要您不调用基本构造函数,它就会起作用。你可以使用讨厌的FormatterServices.GetUninitializedObject()技巧从这里开始:使用反射在 C# 中创建没有默认构造函数的类型实例 https://stackoverflow.com/questions/390578/creating-instance-of-type-without-default-constructor-in-c-sharp-using-reflectio
然后:
public void AnotherBadClassConstructorTest()
{
BadClassMock badClassMock = (BadClassMock)FormatterServices.GetUninitializedObject(typeof(BadClassMock));
badClassMock.InitForTest();
AnotherBadClass anotherBadClass = new AnotherBadClass(badClassMock);
Assert.IsNotNull(anotherBadClass);
}
是的,这是一个相当大的解决方法。显然最好的办法就是说服作者修改代码。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)