Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用摩尔测试虚拟方法?_C#_Unit Testing_Moles - Fatal编程技术网

C# 如何使用摩尔测试虚拟方法?

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

如何使用Moles测试
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能够生成“访问器”——公开任何受保护/私有成员的特殊程序集。不幸的是,他们似乎已经取消了对该功能的支持(尽管我不记得在哪里读过)。