2010-02-12 6 views
6

유닛을 코드베이스로 테스트 할 때 모의 객체를 활용하는 데 필요한 이야기의 징조는 무엇인가?유닛 테스트 void 메쏘드/객체 객체의 말 표지를 조롱하다

코드베이스의 다른 객체를 많이 호출하는 것처럼 간단할까요?

또한 값을 반환하지 않는 테스트 메서드를 어떻게 구성 할 수 있습니까? 그래서 메서드가 void를 리턴하지만 파일로 출력하는 경우, 파일의 내용을 검사하나요?

모킹은 외부 종속성을위한 것이므로 문자 그대로 모든 것입니까? 파일 시스템, 데이터베이스, 네트워크 등 ...

+0

마지막 점은 http://martinfowler.com/articles/mocksArentStubs.html에서 귀하가 그 차이점을 알고 계신지 확인하십시오. – Finglas

+0

그 중 몇 가지 질문을 다루기에 좋은 읽을 거리 : http://xunitpatterns.com/TestStrategy.html –

답변

2

무엇이든간에, 나는 아마도 mocks를 사용합니다.

클래스가 다른 클래스를 호출 할 때마다 일반적으로 호출을 모의하고 올바른 매개 변수로 호출했는지 확인합니다. 그렇지 않은 경우, 조롱 된 객체의 구체적인 코드가 올바르게 작동 하는지를 검사하는 단위 테스트를 갖습니다.

예 :

[Test] 
public void FooMoo_callsBarBaz_whenXisGreaterThan5() 
{ 
    int TEST_DATA = 6; 
    var bar = new Mock<Bar>(); 
    bar.Setup(x => x.Baz(It.Is<int>(i == TEST_DATA))) 
     .Verifiable(); 

    var foo = new Foo(bar.Object); 

    foo.moo(TEST_DATA); 

    bar.Verify(); 
} 

... 
[Test] 
public void BarBaz_doesSomething_whenCalled() 
{ 
    // another test 
} 

나를 위해 일이며, 나는 하나의 큰 글로브로 많은 클래스를 테스트하려고하면, 다음 설정 코드의 톤은 일반적으로있다. 모든 의존성에 대해 머리를 터트 리려고 할 때 읽기가 어려울뿐만 아니라 변경이 필요할 때 매우 취약합니다.

나는 작은 간결한 테스트를 선호합니다. 작성하기가 쉽고, 유지 보수가 쉽고, 테스트의 의도를 더 쉽게 이해할 수 있습니다.

+4

내부 구현 세부 사항에 대한 연결 테스트가 끝나면 더 자주 깨지는 경향이 있습니다. 상태 기반 테스트를 사용하면 출력에만 신경을 씁니다. Mock은 일반적으로 설정하기가 더 쉽지만, 유닛 테스트에서 확실히 위치합니다. – Finglas

-1

단위 테스트는 자체 내에서 자율적으로 작동하는 코드 한 개에만 해당됩니다. 이것은 그것이 다른 작업에 의존하지 않는다는 것을 의미합니다. Test-Driven 프로그래밍 또는 Test-First 프로그래밍을 수행하는 경우 mock을 사용해야합니다. 생성하려는 함수에 대한 mock (또는 스텁 (stub))을 작성하고 테스트가 통과하는 특정 조건을 설정합니다. 원래 함수는 false를 반환하고 테스트는 실패합니다. 예상되는대로 ... 그러면 코드가 작성 될 때까지 실제 작업을 수행합니다.

하지만 내가 말하는 것은 단위 테스트가 아닌 통합 테스트입니다. 이 경우 다른 프로그래머가 작업을 끝내기를 기다리고 있고 현재 작성중인 함수 나 객체에 액세스 할 수없는 경우 mock을 사용해야합니다. 인터페이스를 알고 있다면, 조롱을하는 것이 무의미하며 시간 낭비가 아니라면, 앞으로 얻으려는 것을 어렴풋이 나오는 버전으로 만들 수 있습니다.

즉, 다른 사람들을 기다리고 작업을 끝내기 위해 무언가가 필요할 때 가짜가 가장 좋습니다.

가능한 경우 항상 값을 반환해야합니다. 때로는 이미 무언가를 반환하고있는 문제가 발생하지만 C 및 C++에서는 출력 매개 변수를 사용하고 오류 검사에 반환 값을 사용할 수 있습니다.

+0

-1 - 이것은 모조와 스텁에 대한 오해에 근거합니다. TDD를 할 때 확실히 기능을 빼 먹는 동안, 그것은 모의 객체가있는 것이 아닙니다. 테스트중인 객체를 조롱하지 마십시오. 종속성을 조롱합니다. – TrueWill

+0

그래, 스텁과 모의 사이에 차이가 있다고 생각해. 내가 한 말을 오해 한 것 같아. 첫 번째 단락에서는 단위 테스트가 무엇인지, 그리고 현재 액세스 권한이 없거나 액세스 권한이없는 실제 객체를 시뮬레이트하는 객체를 어떻게 사용할 것인지 설명했습니다. 두 번째 단락에서 나는 모의 테스트가 통합 테스트를위한 것이라고 설명하기 시작했다. 그러나 나는 틀렸다. 통합 테스트는 단위 테스트 후에 수행되며 모의 객체가 아니라 실제 객체로 수행됩니다. 어느 쪽이든, 모의 (mock)는 통합하기 전에 단위 테스팅을하고 싶을 때 가장 잘 활용됩니다. –

0

모의/스텁/가짜/테스트 더블/등. 단위 테스트에서는 문제가 없으며 테스트중인 클래스/시스템을 개별적으로 테스트 할 수 있습니다. 통합 테스트는 모의 (mocks)를 사용하지 않을 수도 있습니다. 그들은 실제로 데이터베이스 또는 다른 외부 의존성에 부딪쳤다.

해야 할 때 mock이나 스텁을 사용합니다. 일반적으로 테스트하려는 클래스가 인터페이스에 종속되어 있기 때문입니다. TDD의 경우 구현이 아닌 인터페이스를 프로그래밍하고 종속성 삽입 (일반적으로 말하면)을 사용합니다.

아주 간단한 경우 :

public class ClassToTest 
{ 
    public ClassToTest(IDependency dependency) 
    { 
     _dependency = dependency; 
    } 

    public bool MethodToTest() 
    { 
     return _dependency.DoSomething(); 
    } 
} 

IDependency는 인터페이스, 고가의 호출 (데이터베이스 액세스, 웹 서비스 호출 등) 가능성이다. 테스트 방법은 유사한 코드가 포함될 수 있습니다 : 나는 (@Finglas가 제안) 상태 테스트를하고 있어요

// Arrange 

var mock = new Mock<IDependency>(); 

mock.Setup(x => x.DoSomething()).Returns(true); 

var systemUnderTest = new ClassToTest(mock.Object); 

// Act 

bool result = systemUnderTest.MethodToTest(); 

// Assert 

Assert.That(result, Is.True); 

참고, 나는 단지 (테스트중인 시스템에 대해 내가 '클래스의 인스턴스를 주장하고있어 m 테스트). 이 경우와 같이 속성 값 (상태) 또는 메서드 반환 값을 확인할 수 있습니다.

특히 .NET을 사용하는 경우 The Art of Unit Testing을 읽는 것이 좋습니다.