簡體   English   中英

單元測試 C# 保護方法

[英]Unit testing C# protected methods

我來自 Java EE 世界,但現在我正在從事一個 .Net 項目。 在 Java 中,當我想測試一個受保護的方法時,這很容易,只要讓測試類具有相同的包名就足夠了。

C# 有類似的東西嗎? 對受保護的方法進行單元測試有什么好的做法嗎? 我只發現框架和人們說我應該只測試公共方法。

應該可以在沒有任何框架的情況下做到這一點......

您可以在測試類上繼承正在測試的類。

[TestClass]
public class Test1 : SomeClass
{
    [TestMethod]
    public void MyTest
    {
        Assert.AreEqual(1, ProtectedMethod());
    }

}

另一種選擇是對這些方法使用internal ,然后使用InternalsVisibleTo允許您的測試程序集訪問這些方法。 這不會阻止同一程序集中其他類使用的方法,但會阻止不是您的測試程序集的其他程序集訪問它們。

這不會為您提供盡可能多的封裝和保護,但它非常直接並且很有用。

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

[assembly: InternalsVisibleTo("TestsAssembly")]

您可以在繼承要測試的類的新類中公開受保護的方法。

public class ExposedClassToTest : ClassToTest
{
    public bool ExposedProtectedMethod(int parameter)
    {
        return base.ProtectedMethod(parameter);
    }
}

您可以使用 PrivateObject 類訪問所有私有/受保護的方法/字段。

PrivateObject 是 Microsoft 單元測試框架中的一個類,它是一個包裝器,可以調用通常無法訪問的成員進行單元測試。

盡管接受的答案是最好的答案,但它並沒有解決我的問題。 從受保護的類派生出很多其他東西污染了我的測試類。 最后我選擇將要測試的邏輯提取到一個公共類中並進行測試。 當然,這並不適用於所有人,並且可能需要進行大量重構,但是如果您一直滾動到這個答案,它可能會幫助您。 :) 這是一個例子

舊情況:

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();
    }
}

您可以使用反射來調用私有和受保護的方法。

請參閱此處了解更多信息:

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

您可以使用從基類調用受保護方法的公共方法創建存根。 這也是您在生產中使用這種受保護方法的方式。

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM