如何使用mole测试虚拟方法
本文关键字:虚拟 方法 测试 mole 何使用 | 更新日期: 2023-09-27 18:15:57
如何使用mole测试IsHappy
函数?
class SomeClass
{
protected virtual bool IsHappy(string mood)
{
return (mood == "Happy");
}
}
我试着用Stub:
来测试SSomeClass stub = new SSomeClass();
stub.CallBase = true;
Assert.IsTrue(stub.IsHappyString("Happy"));
…但是IsHappyString
方法返回null,从而抛出NullReference
异常。
那么,如何测试IsHappy
方法的默认实现呢?
这里我就不提存根了。存根/模拟用于想要模拟依赖项的行为。你会存根你的someeclass,如果有你想测试的someeclassclient,它使用someeclass:
public class Foo
{
public virtual int GetFoosInt()
{
return 12;
}
}
public class FooClient
{
private Foo _foo;
public FooClient(Foo foo)
{
_foo = foo;
}
public int AddOneToFoosInt()
{
return _foo.GetFoosInt() + 1;
}
}
在这个例子中,当测试FooClient时,你想测试的是它返回比"GetFoosInt()"多一个。实际上你并不关心FoosInt是什么来测试FooClient。所以,你可以创建一个Foo存根,在那里你可以设置GetFoosInt来返回你想要的任何东西。
在您的例子中,测试一个受保护的虚拟成员,我会这样做:
[TestClass]
public class SomeClassTest
{
private class DummySomeClass : SomeClass
{
public bool IsHappyWrapper(string mood)
{
return IsHappy(mood);
}
}
[TestMethod]
public void SomeTest()
{
var myClass = new DummySomeClass();
Assert.IsTrue(myClass.IsHappyWrapper("Happy"));
}
}
这让你"直接"访问受保护的虚拟来测试默认行为。唯一需要注意的是,如果您开始定义抽象成员并将它们添加到SomeClass中,那么您也必须将它们添加到这个虚拟继承程序中,从而增加了测试维护开销。
我的纯粹主义者认为,应该不去管受保护的成员,只通过公共接口测试它们。但是,在你的情况下,这可能是可行的,也可能不是,我真的没有看到这种方法有什么害处。
stub和mole用于将一个类从它拥有的任何依赖中隔离出来,无论是环境依赖还是类依赖。这个类没有任何依赖关系,所以为什么要尝试将其移除或存根呢?
如果您想要确保这个基类在人们重写它时能够正常工作,那么您将需要创建一个测试实现。在这种情况下,您的测试用例或多或少应该是这样的:
public SomeClassTestAdapter : SomeClass
{
public bool GetIsHappy(string mood)
{
return IsHappy(mood);
}
}
[Test]
public void ShouldReturnTrueWhenPassedHappy()
{
var classUnderTest = new SomeClassTestAdapter();
bool result = classUnderTest.IsHappy("Happy");
Assert.IsTrue(result, "Expected result to be true");
}
[Test]
public void ShouldReturnFalseWhenPassedLowerCaseHappy()
{
var classUnderTest = new SomeClassTestAdapter();
bool result = classUnderTest.IsHappy("happy");
Assert.IsFalse(result, "Expected result to be false");
}
[Test]
public void ShouldReturnFalseWhenPassedNull()
{
var classUnderTest = new SomeClassTestAdapter();
bool result = classUnderTest.IsHappy(null);
Assert.IsFalse(result, "Expected result to be false");
}
等。
在这段代码中没有任何地方应该挤进存根或摩尔。
如果你不想为这种情况创建一个适配器类,你可以使用内置的。net特性,而不是像mole那样的大型付费依赖。反射和动态允许您访问受保护或私有成员。请看下面的例子:
- http://igoro.com/archive/use-c-dynamic-typing-to-conveniently-access-internals-of-an-object/