2017-09-26 15 views
-5

私は単体テストプライベートメソッドの素晴らしい方法を発見しました。C#でプライベートオブジェクトの型の安全を作成する方法

これは、メソッド名が文字列としてどのように入力されるのか気に入らない限り、素晴らしいことです。 「安全ネット」を作る方法はありますか?メソッドがオブジェクトに存在しない場合、コンパイラがコンパイラの時間エラーをスローできるように、メソッド名を入力します。

プライベートメソッド:

public class BankAccount 
{ 
    //Private method to test 
    private bool VerifyAmount(double amount) 
    { 
     return (amount <= 1000); 
    } 
} 

単体テスト:

[TestMethod()]   
public void VerifyAmountTest() 
{ 
    //Using PrivateObject class 
    PrivateObject privateHelperObject = new PrivateObject(typeof(BankAccount));        
    double amount = 500F; 
    bool expected = true; 
    bool actual; 
    actual = (bool)privateHelperObject.Invoke("VerifyAmount", amount);    
    Assert.AreEqual(expected, actual);    
} 

私は何人かの人々は、我々はユニットテストのプライベートメソッドべきではないと考えていることを知っています。それはこの質問の目的ではないので、その質問について話し合わずに話題に留もう。

+6

プライベートメソッドをテストすべきではないと考えましたか? – CodeCaster

答えて

-2

.NETオブジェクトでprivateメソッドの存在を確認したいですか?あなたが必要な場合は

var typeOfObj = typeof(BancAccount) 
       .GetMethods(
       BindingFlags.NonPublic | 
       BindingFlags.Instance) 
       .Any(method => method.Name == testedName) 

ケース2:あなたはメソッドのシグネチャを気にしない場合は

ケース1

次にインスタンスから任意のメソッドを抽出するために、次の例1を選びます正確な署名を指定してから使用する - typeof(BancAccount).GetMethod(testedName, <types of arguments>)

+0

いいえ、彼らの質問は_ "文字列に頼らずにプライベートプロパティを参照する方法" _です。 – CodeCaster

+0

彼はプライベートメソッドをテストしたいと思っていますし、今はリフレクションを使って名前でそれをやっています。 – JuanR

+0

この場合、 "testedName"はメソッドの名前を表す文字列ではありませんか? – Maderas

0

クラスを単体テストするときは、基本的に消費者の帽子を入れてのクラスのメソッドは、クラスがそれが何をするかを検証するメソッドです。例えば

、あなたのBankAccountクラスを使用してこの例を考えてみます。

public class BankAccount 
{ 
    public Widthdrawal WithdrawMoney(double amount) 
    { 
      if(!VerifyAmount(amount)) 
       throw new InvalidOperationException("Minimum dispensed is $1,000!"); 
      //Do some stuff here 
      return new Withdrawal(1000); 
    } 
    private bool VerifyAmount(double amount) 
    { 
     return (amount <= 1000); 
    } 

} 

あなたはその後、いくつかのことをテストすることができます。たとえば:

  1. 有効な金額が払い戻しになります。
  2. 無効な値は無効な操作例外になります。

あなたのテスト:

[TestMethod] 
public void Verify_Valid_Amount_Results_In_Widtdrawal() 
{ 
    var bankAccount = new BankAccount(); 
    var withdrawal = bankAccount.WithdrawMoney(1200); 
    Assert.IsNotNull(withdrawal); 
    Assert.AreEqual(1200, withdrawal); 
} 


[TestMethod] 
[ExpectedException(typeof(InvalidOperationException))] 
public void Verify_Valid_Amount_Results_In_Exception() 
{ 
    var bankAccount = new BankAccount(); 
    var withdrawal = bankAccount.WithdrawMoney(800); 
} 

あなたが見ることができるように、あなたはプライベートメソッドではなく、プライベートメソッド自体を使用していますfuncionalityをテストします。

このメソッドを確認することが重要な場合は、このメソッドを公開するか、またはこのメソッドを公開する別のクラスに金額検証の概念を抽象化するか、単体でテストすることができます。

+1

単体テストにはさまざまな視点があります。あなたは私の質問には答えませんでした。あなたはトピックから外れています。 – Maderas

+1

_unit testing_ == _ class _のパブリックインターフェイスのテスト_と考えるのはよくある誤解です。名前そのものが言うように、それは "_unit_のテスト"です。ここで、_unit_は_unit_funcionality_です。プライベート/内部のメソッドをテストするのは完全に合法です。 C#やJavaのような言語では、Reflectionやハードコーディングされた文字列を使用する必要があります。難しくて面倒です。他の言語(Python)では、プライベートメソッドがまったくないので、すべてのメソッドを "private"アンダースコアを使用していますが、これは単なる規約であり、公的なものと同様にアクセスしてテストすることができます。 –

+0

@MassimilianoKraus:これを哲学的な戦争に変えてはいけません。これは私の最後のコメントです。メソッド自体をテストする場合は、元のオブジェクトに渡すことができる別のクラスへの金額の検証の概念を公開または抽象化することができます。そうすれば、金額ロジックを個別に検証することができます。 Pythonの機能としてアクセス制御が不足していることがあります。私はそれがミスだと思う。とにかく、彼自身にそれぞれ。 :-) – JuanR

関連する問題