Object Mothers로 테스트 데이터를 생성하는 방법

11569 단어 csharpbeginnerstesting
원래 몇 주 전에 이 게시물on my blog의 확장 버전을 게시했습니다. "Unit Testing 101"이라는 제목으로 게시한 시리즈의 일부입니다.

write better tests에 대한 한 가지 팁은 테스트 내부의 노이즈를 줄이는 것입니다. 이를 위해 빌더 메소드를 사용할 수 있습니다. 테스트의 복잡한 부품 정렬 또는 설정 시나리오를 단순화하는 데 도움이 됩니다.

이번에는 Object Mothers를 사용하여 테스트 데이터를 생성할 때 단위 테스트 내부의 노이즈를 줄여보겠습니다.

대상 어머니 없이



신용카드를 인증해 봅시다. FluentValidation 라이브러리를 사용하여 유효성 검사기 클래스를 만듭니다. 신용 카드가 만료되었는지 확인하고 싶습니다. 우리는 이와 같은 테스트를 작성할 수 있습니다.

using FluentValidation.TestHelper;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;

namespace UsingObjectMothers
{
    [TestClass]
    public class CreditCardValidationTests
    {
        [TestMethod]
        public void CreditCard_ExpiredYear_ReturnsInvalid()
        {
            var validator = new CreditCardValidator();

            var creditCard = new CreditCard
            {
                CardNumber = "4242424242424242",
                ExpirationYear = DateTime.Now.AddYears(-1).Year,
                ExpirationMonth = DateTime.Now.Month,
                Cvv = 123
            };
            var result = validator.TestValidate(creditCard);

            result.ShouldHaveAnyValidationError();
        }

        [TestMethod]
        public void CreditCard_ExpiredMonth_ReturnsInvalid()
        {
            var validator = new CreditCardValidator();

            var creditCard = new CreditCard
            {
                CardNumber = "4242424242424242",
                ExpirationYear = DateTime.Now.Year,
                ExpirationMonth = DateTime.Now.AddMonths(-1).Month,
                Cvv = 123
            };
            var result = validator.TestValidate(creditCard);

            result.ShouldHaveAnyValidationError();
        }
    }
}

이 테스트에서는 FluentValidation의 TestValidate()ShouldHaveAnyValidationError() 메서드를 사용하여 더 나은 어설션을 작성했습니다.

각 테스트에서 주어진 시나리오에 대해 CreditCard 개체를 만들고 단일 속성을 수정했습니다. CreditCard 개체를 초기화할 때 중복 및 매직 값이 있었습니다.

개체 어머니



우리의 테스트에서 우리는 독자들에게 충분한 세부 정보를 제공해야 하지만 테스트를 시끄럽게 만들 정도로 세부 정보를 너무 많이 제공해서는 안 됩니다. 세부 사항을 적절한 수준으로 유지해야 합니다.

이전 테스트에서는 각 테스트에서 만료 연도와 월만 신경썼습니다. 반복을 피하기 위해 CreditCard 객체 생성을 추상화할 수 있습니다.
CreditCard 객체 생성을 추상화하는 한 가지 대안은 객체 어머니를 사용하는 것입니다.

객체 어머니는 바로 사용할 수 있는 입력 객체를 보유하는 팩토리 메서드 또는 속성입니다. 각 테스트 내에서 이 개체의 속성은 테스트 중인 시나리오와 일치하도록 업데이트됩니다.

이 예에서는 유효한 기본값으로 CreditCard 속성을 만들고 각 테스트 내에서 조정할 수 있습니다.

신용 카드용 개체 어머니를 사용한 테스트는 다음과 같습니다.

[TestClass]
public class CreditCardValidationTests
{
    [TestMethod]
    public void CreditCard_ExpiredYear_ReturnsInvalid()
    {
        var validator = new CreditCardValidator();

        // Instead of creating a new card object each time,
        // we rely on this new CreditCard property
        var request = CreditCard;
        request.ExpirationYear = DateTime.Now.AddYears(-1).Year;
        var result = validator.TestValidate(request);

        result.ShouldHaveAnyValidationError();
    }

    [TestMethod]
    public void CreditCard_ExpiredMonth_ReturnsInvalid()
    {
        var validator = new CreditCardValidator();

        var request = CreditCard;
        request.ExpirationMonth = DateTime.Now.AddMonths(-1).Month;
        var result = validator.TestValidate(request);

        result.ShouldHaveAnyValidationError();
    }

    // We have this new property to hold a valid credit card
    private CreditCard CreditCard
        => new CreditCard
        {
            CardNumber = "4242424242424242",
            ExpirationYear = DateTime.Now.Year,
            ExpirationMonth = DateTime.Now.Month,
            Cvv = 123
        };
}

테스트 클래스의 CreditCard 속성과 테스트에서 해당 값을 업데이트하는 방법에 주목하십시오.

짜잔! 이것이 개체 어머니를 사용하여 테스트 데이터를 만들고 테스트를 단순화하는 방법입니다. 간단한 트릭이죠?

생성되는 개체의 변형이 많지 않은 경우 개체 어머니가 좋습니다. 하지만 그럴 경우 빌더를 사용하십시오. 빌더에 대해 알아보려면 the Builder pattern에 대한 내 게시물을 확인하십시오.

테스트에서 독자에게 충분한 세부 정보를 제공해야 하지만 테스트가 시끄럽게 만들 정도로 너무 많지 않아야 함을 기억하십시오. 테스트 독자를 지루하게 만들지 말고 그들을 놀라게 하지도 마십시오.

단위 테스트 작성을 연습하려면 내Unit Testing 101 저장소를 확인하십시오.


canro91 / 테스팅101


초보자를 위한 단위 테스트 워크숍





단위 테스트를 처음 사용하거나 자세히 알아보려면 my blog에서 내 "단위 테스트 101"시리즈를 계속 시청하십시오.

행복한 테스트!

좋은 웹페이지 즐겨찾기