문제

그래서 나는 공장 수업이 있고 단위 테스트가 무엇을 해야하는지 알아 내려고 노력하고 있습니다. 이것으로부터 의문 반환 된 인터페이스가 내가 기대할 특정 콘크리트 유형인지 확인할 수 있습니다.

공장이 콘크리트 유형을 반환하는지 확인 해야하는지 확인해야합니다 (현재 인터페이스를 사용해야 할 필요가 없기 때문에)? 현재 나는 다음과 같은 일을하고 있습니다.

[Test]
public void CreateSomeClassWithDependencies()
{
    // m_factory is instantiated in the SetUp method
    var someClass = m_factory.CreateSomeClassWithDependencies();

    Assert.IsNotNull(someClass);
}

이것의 문제는 Assert.IsNotNull 다소 중복되는 것 같습니다.

또한 내 공장 방법은 다음과 같은 특정 클래스의 종속성을 설정하고있을 수 있습니다.

public SomeClass CreateSomeClassWithDependencies()
{
    return new SomeClass(CreateADependency(), CreateAnotherDependency(),
                         CreateAThirdDependency());
}

그리고 공장 방법이 이러한 모든 종속성을 올바르게 설정하도록하고 싶습니다. 그러한 종속성을 만들기 위해 이것을 할 수있는 다른 방법이 없습니까? public/internal 속성 단위 테스트에서 확인한 속성? (나는 테스트에 맞게 시험 대상을 수정하는 큰 팬이 아닙니다)

편집 : Robert Harvey의 질문에 대한 응답으로, 나는 Nunit을 단위 테스트 프레임 워크로 사용하고 있습니다 (그러나 그것이 너무 많은 차이를 만들 것이라고 생각하지 않았을 것입니다).

도움이 되었습니까?

해결책

종종 국가 기반 테스트에 사용할 수있는 공개 속성을 만드는 데 아무런 문제가 없습니다. 예 : 테스트 시나리오를 활성화하기 위해 작성한 코드이지만 API가 손상됩니까? 다른 고객이 나중에 동일한 속성을 유용하게 찾을 수 있습니까?

테스트 별 코드와 테스트 중심 디자인 사이에는 미세한 선이 있습니다. 테스트 요구 사항을 충족하는 것 외에 다른 잠재력이없는 코드를 도입해서는 안되지만 일반적으로 허용되는 설계 원칙을 따르는 새로운 코드를 도입하는 것은 매우 괜찮습니다. 우리는 테스트를하게했습니다 운전하다 우리의 디자인 - 그것이 우리가 그것을 TDD라고 부르는 이유입니다 :)

클래스에 하나 이상의 속성을 추가하여 사용자에게 클래스를 검사 할 가능성을 더 잘 제공하는 것이 제 생각에 종종 합리적인 일이므로 그러한 속성을 도입하는 것을 무시해야한다고 생각하지 않습니다.

그 외에도, 나는 두 번째 Nader의 대답 :)

다른 팁

공장이 콘크리트 유형을 반환하고 있고 공장이 항상 콘크리트 유형을 반환한다는 것을 보장하는 경우, 그렇지 않으면 없습니다. ~도 테스트에서 많은 가치. 시간이 지남에 따라이 기대가 위반되지 않으며 예외와 같은 것들이 던져지지 않도록 할 수 있습니다.

이 스타일의 테스트는 단순히 미래에 변화를 겪을 때 공장 행동을 모르면 변하지 않도록합니다.

귀하의 언어가 지원하는 경우 의존성의 경우 반성을 사용할 수 있습니다. 이것은 항상 유지하기 가장 쉬운 것은 아니며 테스트를 구현에 매우 단단히 연결합니다. 그것이 허용되는지 결정해야합니다. 이 접근법은 매우 부서지기 쉬운 경향이 있습니다.

그러나 당신은 실제로 생성자 호출 방식과 어떤 클래스를 구성하는지 분리하려고하는 것 같습니다. DI 프레임 워크를 사용하여 그런 종류의 유연성을 얻는 것이 더 나을 수도 있습니다.

에 의해 new-필요한대로 모든 유형을 만들면 많은 이음새를 제공하지 않습니다 (이음새는 그 장소에서 편집하지 않고 프로그램의 동작을 변경할 수있는 곳)를 제공하지 않습니다.

그래도 예를 들어 공장에서 수업을 도출 할 수 있습니다. 그런 다음 재정의 / 조롱합니다 CreateADependency(), CreateAnotherDependency() 그리고 CreateAThirdDependency(). 이제 전화 할 때 CreateSomeClassWithDependencies(), 당신은 할 수 있습니다 감각 올바른 종속성이 생성되었는지 여부.

참고 : "Seam"의 정의는 Michael Feather의 저서 인 "레거시 코드와 효과적으로 작동"에서 나온 것입니다. 테스트되지 않은 코드에 테스트 가능성을 추가하기위한 많은 기술의 예가 포함되어 있습니다. 당신은 그것이 매우 유용하다고 생각할 수 있습니다.

우리가하는 일은 공장과의 의존성을 만드는 것입니다. 우리는 테스트가 실행될 때 실제 공장을 대체하기 위해 의존 주입 프레임 워크를 사용합니다. 그런 다음 모의 공장에 대한 적절한 기대치를 설정했습니다.

당신은 항상 반사로 물건을 확인할 수 있습니다. 단위 테스트를 위해 무언가를 노출시킬 필요가 없습니다. 나는 반사로 도달해야한다는 것이 드물며 나쁜 디자인의 표시 일 수 있습니다.

샘플 코드를 살펴보면, 공장을 설계하는 방식에 따라 널이없는 것은 널리없는 것 같습니다. 일부는 예외와 달리 공장에서 널 개체를 반환합니다.

이해할 수 있듯이 종속성이 올바르게 구축되어 새 인스턴스로 전달되는 것을 테스트하고 싶습니까?

Google Guice와 같은 프레임 워크를 사용할 수 없다면 아마도 다음과 같은 일을 할 것입니다 (여기서 Jmock 및 Hamcrest를 사용하여).

@Test
public void CreateSomeClassWithDependencies()
{
    dependencyFactory = context.mock(DependencyFactory.class);
    classAFactory = context.mock(ClassAFactory.class);

    myDependency0 = context.mock(MyDependency0.class);
    myDependency1 = context.mock(MyDependency1.class);
    myDependency2 = context.mock(MyDependency2.class);
    myClassA = context.mock(ClassA.class);

    context.checking(new Expectations(){{
       oneOf(dependencyFactory).createDependency0(); will(returnValue(myDependency0));
       oneOf(dependencyFactory).createDependency1(); will(returnValue(myDependency1));
       oneOf(dependencyFactory).createDependency2(); will(returnValue(myDependency2));

       oneOf(classAFactory).createClassA(myDependency0, myDependency1, myDependency2);
       will(returnValue(myClassA));
    }});

    builder = new ClassABuilder(dependencyFactory, classAFactory);

    assertThat(builder.make(), equalTo(myClassA));
}

(Classa를 조롱 할 수없는 경우 New를 사용하여 MyClassa에 비 모의 버전을 할당 할 수 있습니다)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top