单元测试C#受保护的方法

时间:2012-11-16 12:01:57

标签: c# .net unit-testing protected

我来自Java EE世界,但现在我正在研究.Net项目。在Java中,当我想测试受保护的方法时,它非常简单,只需让具有相同包名的测试类就足够了。 C#有什么类似的东西吗?单元测试受保护的方法有什么好的做法吗?我只发现框架和人们说我应该只测试公共方法。 应该可以在没有任何框架的情况下做到这一点......

非常感谢。

7 个答案:

答案 0 :(得分:66)

您可以继承正在测试类上测试的类。

public class Test1 : SomeClass
{
    Asert.AreEqual(1, SomeClass.ProtectedMethod());
}

答案 1 :(得分:20)

另一个选择是对这些方法使用internal,然后使用InternalsVisibleTo允许测试程序集访问这些方法。这并不会停止同一程序集中其他类所使用的方法,但它会阻止它们被不是您的测试程序集的其他程序集访问。

这并不能为您提供尽可能多的封装和保护,但它非常简单并且非常有用。

在包含内部方法的程序集中添加到AssemblyInfo.cs

[assembly: InternalsVisibleTo("TestsAssembly")]

答案 2 :(得分:11)

您可以在继承要测试的类的新类中公开受保护的方法。

copy.indexOf()

答案 3 :(得分:5)

您可以使用PrivateObject类访问所有私有/受保护的方法/字段。

PrivateObject是Microsoft单元测试框架中的一个类,它是一个包装器,可以调用通常无法访问的成员进行单元测试。

答案 4 :(得分:3)

您可以使用反射来调用私有和受保护的方法。

请点击此处了解更多信息:

http://msdn.microsoft.com/en-us/library/66btctbe.aspx

答案 5 :(得分:1)

尽管公认的答案是最好的答案,但这并不能解决我的问题。从受保护的类派生而来的还有很多其他东西污染了我的测试类。最后,我选择将要测试的逻辑提取到公共类中并进行测试。当然,这对每个人都不起作用,并且可能需要进行一些重构,但是如果您一直滚动到此答案,则可能会对您有所帮助。 :)这是一个例子

旧情况:

protected class ProtectedClass{
   protected void ProtectedMethod(){
      //logic you wanted to test but can't :(
   }
}

新情况:

protected class ProtectedClass{
   private INewPublicClass _newPublicClass;

   public ProtectedClass(INewPublicClass newPublicClass) {
      _newPublicClass = newPublicClass;
   }

   protected void ProtectedMethod(){
      //the logic you wanted to test has been moved to another class
      _newPublicClass.DoStuff();
   }
}

public class NewPublicClass : INewPublicClass
{
   public void DoStuff() {
      //this logic can be tested!
   }
}

public class NewPublicClassTest
{
    NewPublicClass _target;
    public void DoStuff_WithoutInput_ShouldSucceed() {
        //Arrange test and call the method with the logic you want to test
        _target.DoStuff();
    }
}

答案 6 :(得分:0)

您可以使用从基类调用受保护方法的公共方法创建存根。这也是您在生产中使用这种受保护方法的方式。

public class FooStub : Bar 
{
    public string MyMethodFoo()
    {
        return MyMethodBar();
    }
}

public abstract class Bar 
{
    protected string MyMethodBar()
    {
        return "Hello World!"
    }
}