단위 테스트 :“리팩토링하고 공동 작업자가 없다면 코드 냄새가나요?”


9

Roy Osherove의 The Unit of Unit Testing을 읽고 있습니다. 저자는 코드 냄새에 대한이 노트를 가지고있는 7.2 절 유지 보수 가능한 테스트 작성에있다.

참고 : 외부 테스트에서 볼 수 있도록 내부 상태를 리팩터링 할 때 코드 냄새 (코드 디자인 또는 로직에 문제가 있음)로 간주 될 수 있습니까? 공동 작업자를 노출시키기 위해 리팩토링 할 때 코드 냄새가 아닙니다. 리팩토링하고 공동 작업자가 없으면 코드 냄새가납니다 (따라서 스텁하거나 조롱 할 필요가 없습니다).

편집 : 저자가 "협업 자"가 의미하는 것은 의존성입니다. 종속성에 대한 그의 예로는 데이터베이스에 액세스하거나 OS의 파일 시스템에 액세스하는 클래스가 있습니다. 여기에서 스텁을 정의하고 공동 작업 자라는 단어를 사용하기 시작합니다.

스텁 기존위한 제어 대체 의존성 (또는 협력자 시스템에서).

저자는이 코드 냄새의 예를 가지고 있지 않으며 이것이 어떻게 보일지 이해하고 이해하는 데 어려움을 겪고 있습니다. 누군가 이것을 조금 더 설명하고 구체적인 예를 제공 할 수 있습니까?


여기서 혼동은 "협업 자"라는 단어에서 비롯된 것 같습니다. 나는이 맥락에서 그가 무엇을 의미하는지 잘 모르겠다.
rossipedia

@Bryan Ross, 저자가 "협업 자"라는 단어를 사용하는 방식으로 게시물을 업데이트했습니다. 감사!
프로그래머

답변:


3

나는 이것이 저자가 얻는 것이라고 생각합니다.

코드 샘플에는 출력 수량에 시작 및 중지 시간을 더한 타이밍 창이 있습니다. 24 시간 동안 출력 창을 그리는 것이 목적입니다. 시작 시간이 중지 시간보다 크면 주름이 추가됩니다. 자정에 걸친 타이밍 창이기 때문입니다.

개인 변수를 노출시키지 않고 객체를 완전히 작동시키는 단위 테스트를 작성할 수 있습니다. 이러한 개인 부울과 기간은 단위 테스트를 위해 내부를 노출 할 때 참조하는 공동 작업자입니다. 이 책에 따르면 그 내부를 노출시키는 것은 공동 작업자이기 때문에 코드 냄새가 나지 않을 것이라고한다.

double output은 공동 작업자가 아니기 때문에 코드 냄새가납니다 GetOutput. 반환해야 할 것을 결정하기 위해 조건부 논리가있는 클래스 자체에 명시 적으로 숨겨져있는 요소 입니다.

부울 / 타임스 팬을 파면 단위 테스트가 더욱 포괄적이됩니다. 그는 이것이 좋다고 말합니다.
이중으로 파고 들기 output위해서는 단위 테스트 GetOutput에서 수행중인 작업 을 반영하는 추가 논리가 필요합니다 . 이것이 그가 말하는 코드 냄새 일 것입니다.

공개 클래스 TimeWindow
{
  개인 bool isConst;
  개인 bool spansMidnight;
  개인 TimeSpan start1;
  개인 TimeSpan stop1;
  개인 TimeSpan start2;
  개인 TimeSpan stop2;
  개인 이중 출력;

  공개 TimeWindow (더블 아웃, TimeSpan 시작, TimeSpan 중지)
  {
    출력 = 출력;

    if (start == stop)
      isConst = true;
    그렇지 않으면 if (start> stop)
    {
      spansMidnight = true;
      start1 = 자정;
      stop1 = 중지;
      start2 = 시작;
      stop2 = 자정;
    }
    그밖에 
    {
      start1 = 시작;
      stop1 = 중지;
    }
  }

  공개 double GetOutput (TimeSpan 시간)
  {
    // 무엇을 / 어떻게 반환하는지에 대한 논리
    ...
    리턴 출력;
  }

}

0

도메인 클래스가 있고이 도메인 클래스에 리포지토리를 사용하는 지속성 계층에 대한 직접적인 지식이 있다고 가정 해 보겠습니다.이 클래스는 도메인 클래스에서 작업하는 객체가 변경 사항을 유지하기 위해 호출 할 수있는 인스턴스 수준의 "저장"메서드를 노출하기 위해 사용합니다. 매커니즘에 대한 지식이 없어도 만들어졌다 (이것이 "좋은"디자인인지 다른 날 토론이다). 이 리포지토리를 속성 및 / 또는 생성자 인수로 노출하도록 클래스를 리팩터링하여 적절한 호출이 이루어질 수 있도록 조롱 된 리포지토리를 전달할 수있게하는 것은 일반적으로 테스트뿐만 아니라 일반적인 유지 관리성에도 좋습니다.

이제 이것은 도메인 클래스이며 상태 데이터가 있습니다. 상태 저장 속성 중 하나에 지원 필드가 있다고 가정하고 속성 접근자는 현재 입력을 기반으로 새 입력이 유효한지 테스트합니다 (새 값이 이전 입력보다 작을 수는 없음). 이 유효성 검사를 테스트해야하지만 그렇게하려면 백업 필드에 액세스하여 덮어 쓸 초기 값을 설정해야합니다. 이것은 붉은 깃발이어야합니다. 테스트가 구현 세부 인 배면 필드에 대한 액세스를 (필요한 경우, 어떤 소비자해야하지 이제까지테스트를 위해 객체를 일관된 상태로 만들려면 프로덕션 코드가 어떻게 일관된 객체를 얻습니까? 프로덕션 코드에서 테스트와 동일한 작업을 수행 할 수있는 방법이 있다면 테스트는 아마도 그 방식을 모방해야합니다. 프로덕션 코드가 오브젝트를이 상태로 가져 오는 올바른 방법이 없다면 왜이 시나리오를 테스트하고 있습니까?

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.