C# 如何使用摩尔测试虚拟方法?
如何使用Moles测试C# 如何使用摩尔测试虚拟方法?,c#,unit-testing,moles,C#,Unit Testing,Moles,如何使用Moles测试IsHappy功能 class SomeClass { protected virtual bool IsHappy(string mood) { return (mood == "Happy"); } } 我尝试使用存根测试是否: SSomeClass stub = new SSomeClass(); stub.CallBase = true; Assert.IsTrue(stub.IsHappyString("Happ
IsHappy
功能
class SomeClass
{
protected virtual bool IsHappy(string mood)
{
return (mood == "Happy");
}
}
我尝试使用存根测试是否:
SSomeClass stub = new SSomeClass();
stub.CallBase = true;
Assert.IsTrue(stub.IsHappyString("Happy"));
。。。但是IsHappyString
方法返回null,从而引发NullReference
异常
那么,我如何测试
IsHappy
方法的默认实现呢?存根和mole用于将类与它所具有的任何依赖项(环境依赖项或类依赖项)隔离开来。这个类没有任何依赖项,所以为什么要尝试mole或stub它呢
如果您想确保在人们重写该基类时该基类能够正常工作,那么您需要创建一个测试实现。在这种情况下,您的测试用例或多或少应该是这样的:
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功能,而不是像Moles这样的大型付费依赖项。反射和动态允许您访问受保护的或私有的成员。请参见此示例:
- 我忘了这里的存根。存根/模拟用于当您想要伪造依赖项的行为时。如果您想要测试SomeClassClient,并且它使用了SomeClass,那么您将存根您的SomeClass:
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"));
}
}
这使您可以“直接”访问受保护的虚拟机以测试默认行为。唯一需要注意的是,如果开始定义抽象成员并将其添加到某个类中,则还必须将其添加到该虚拟继承器中,从而增加测试维护开销
我身上的纯粹主义者说,应该让受保护的成员独处,只通过公共接口测试它们。但是,在你的情况下,这可能是可行的,也可能是不可行的,我真的不认为这种方法有什么害处 IsHappy方法受
保护
。我无法通过直接从被测类调用该方法来访问它。@Ian:很抱歉,花了这么长时间才回到这个问题。更新了我的答案Moles.NET中是否有可以“自动化”此功能的设施?在鼹鼠身上有一些行为控制(漏检等)。这些可以用来代替手动创建一个虚拟类吗?我不知道。我主要使用Moles来模拟外部依赖项,如第三方静态方法、文件、GUI等。我没有将它作为一个通用的模拟引擎使用过很多次,而是选择使用Moq。Moles功能非常强大,因此如果这是可能的话,我也不会感到惊讶,但不幸的是,我不知道它到底有多强大。早些时候,MSTest能够生成“访问器”——公开任何受保护/私有成员的特殊程序集。不幸的是,他们似乎已经取消了对该功能的支持(尽管我不记得在哪里读过)。