6

以下のように、その操作が依存関係に依存するメソッドがあります。単体テストを行う価値はまだありますか?単体テストはモックによってではなく、ビジネス ロジックをテストしていないためです。

以下の単体テスト:

expectedCustomerValidalityメソッドの操作は、テストによってセットアップされるによって決定されることに注意してください。ほとんどの場合、ロジックはモックによって決定されます (例: Setup(c => c.IsValid()).

        [Test]
        [TestCase(true)]
        [TestCase(false)]
        public void AddCustomer(bool expectedCustomerValidality)
        {
           //using Moq
            companyRepositoryMock.Setup(c => c.GetById(It.IsAny<int>())).Returns(new Company());          
            customerValidatorMock.Setup(c => c.IsValid(It.IsAny<Customer>())).Returns(expectedCustomerValidality);

            var customer = new Customer
                               {
                                   Firstname = "firstName",
                                   Surname = "surname",
                                   Company = new Company { Id = 1 }
                               };

            var addCustomer = customerServiceSut.AddCustomer(customer);

            Assert.AreEqual(expectedCustomerValidality,addCustomer);
        }

以下のプロダクションコード:

 public class CustomerService : ICustomerService
    {
        private ICompanyRepository companyRepository;
        private ICustomerRepository customerRepository;
        private ICustomerValidator customerValidator;

        public CustomerService(ICompanyRepository companyRepository, ICustomerRepository customerRepository, ICustomerValidator customerValidator)
        {
            this.companyRepository = companyRepository;
            this.customerRepository = customerRepository;
            this.customerValidator = customerValidator;

        }

        public bool AddCustomer(Customer customer)
        {           
            customer.Company = companyRepository.GetById(customer.Company.Id); ;

            if (customerValidator.IsValid(customer))
            {
                customerRepository.AddCustomer(customer);

                return true;
            }

            return false;
        }
}

質問:

  • AddCustomer() には単体テストが必要ですか?
  • もしそうなら、現在の単体テストは正しい方法で実行されていますか?

    1 そうでない場合、それを単体テストする適切な方法は何ですか?

4

2 に答える 2

7

私はこれが好きではありません。理由は次のとおりです。テスト メソッド名は、テスト対象のメソッド、テストの前提条件、およびテストの結果を期待するものを反映する必要があります。

public bool AddCustomer_CustomerIsValid_ShouldReturnTrue()

public bool AddCustomer_CustomerIsInvalid_ShouldReturnFalse()

必要に応じて、コア テスト ロジックを独自のメソッドにリファクタリングしてコードの重複をなくし、上記の 2 つのメソッドからそのメソッドを呼び出すことができます。しかし、リファクタリングされたメソッドはテスト ケースではありません。これは、実際のテスト ケースの単なるヘルパー メソッドです。

例:

[Test]
public void AddCustomer_CustomerIsValid_ShouldReturnTrue()
{
    var result = AddCustomerTest(true);
    Assert.IsTrue(result);
}

[Test]
public void AddCustomer_CustomerIsInvalid_ShouldReturnFalse()
{
    var result = AddCustomerTest(false);
    Assert.IsFalse(result);
}

public void AddCustomerTest(bool expectedCustomerValidality)
{
   //using Moq
    companyRepositoryMock.Setup(c => c.GetById(It.IsAny<int>())).Returns(new Company());          
    customerValidatorMock.Setup(c => c.IsValid(It.IsAny<Customer>())).Returns(expectedCustomerValidality);

    var customer = new Customer
    {
        Firstname = "firstName",
        Surname = "surname",
        Company = new Company { Id = 1 }
    };

    var result= customerServiceSut.AddCustomer(customer);

    return result;
}
于 2013-07-12T02:37:45.790 に答える
0

AddCustomerビジネスロジックを実行するため、テストが必要です。会社を取得して設定し、データを検証し、データをリポジトリに追加し、結果を返します。

あなたのテストはほぼ正しいです。すべてのビジネス ロジックを検証するために、もう少し具体的にします。

[Test]
[TestCase(true)]
[TestCase(false)]
public void AddCustomer(bool isCustomerValid)
{
     //arrange
     //NOTE!!! create the mocks with MockBehavior.Strict
     //that way the test will fail if a call is made w/o setup

     const long testCompanyId = 100;
     var testCompany = new Company{ Id = testCompanyId };
     companyRepository.Setup(r => r.GetById(testCompanyId))
          .Returns(testCompany);

     var testCustomer = new Customer
                   {
                        Firstname = "firstName",
                        Surname = "surname",
                        Company = new Company { Id = testCompanyId }
                   };

     customerValidatorMock.Setup(c => c.IsValid(It.Is<Customer>(c => c == testCustomer && c.Company == testCompany)).Returns(isCustomerValid);

     if (isCustomerValid)
     {
          customerRepository.Setup( r => r.AddCustomer(testCustomer) ). Verifiable();
     }

     //act        
     var addCustomerResult = customerServiceSut.AddCustomer(testCustomer);

     //assert
     Assert.AreEqual(isCustomerValid, addCustomerResult);
     cutomerRepository.VerifyAll();
}

上記のテストでは、サービス メソッドのすべての機能がテストされます。これには、会社が ID でフェッチされるかどうか、フェッチされたものが使用されるかどうかが含まれます。また、有効な場合、顧客が追加されているかどうかを確認します。有効でない場合に顧客が追加されると、テストは失敗します (customerRepository が MockBehavior.Strict で作成され、セットアップが実行されないため)。

于 2013-07-15T16:13:38.760 に答える