-5

我发现了一种对私有方法进行单元测试的绝妙方法。

这很好,除了我不喜欢方法名称作为字符串输入的方式。有没有办法建立一个“安全网”?我想键入方法名称,以便编译器可以在对象上不存在该方法时抛出编译器时错误。

私有方法:

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

我知道有些人认为我们不应该对私有方法进行单元测试。这不是这个问题的目的,所以让我们不要讨论这个问题并继续讨论这个话题。

4

2 回答 2

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

如您所见,您测试的是使用私有方法的功能,而不是私有方法本身。

如果验证该方法对您很重要,您可以将其公开或将数量验证的概念抽象到另一个公开此方法并且可以单独进行单元测试的类。

于 2017-09-26T13:31:17.197 回答
-2

private你想检查.Net 对象上是否存在方法,我说得对吗?

然后选择以下情况之一从实例中提取任何方法:

案例 1如果您不关心方法签名:

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

案例 2如果您需要指定确切的签名,请使用 - typeof(BancAccount).GetMethod(testedName, <types of arguments>)

于 2017-09-26T13:14:16.567 回答