모의 객체는 일반적으로 어떻게 잘못 사용됩니까?


15

나는 최근에 모의 객체가 종종 오해되고 오용되었다는 기사를 읽었습니다. 내가 볼 수있는 명확한 조롱 방지 패턴이 있습니까?



아니요. 정확한 출처를 기억할 수는 없지만 게시하면 여기에 게시됩니다.
Armand

mongodb API를 조롱하기 위해 stackoverflow를 수행했습니다. 본인이 작성하지 않은 수업을 조롱하는 것이 잘못되었다고 주장하는 블로그 게시물을 지적했습니다. 나는 실제로 이것에 동의하지 않지만 의견이 있습니다.
케빈

답변:


13

나는 간단한 구체적인 수업이 조롱되는 것을 싫어합니다. 예를 들어 다른 것에 의존하지 않는 다음과 같은 간단한 클래스를 사용하십시오.

public class Person
{
    private readonly string _firstName;
    private readonly string _surname;

    public Person(string firstName, string surname)
    {
        if (String.IsNullOrEmpty(firstName))
        {
            throw new ArgumentException("Must have first name");
        }

        if (String.IsNullOrEmpty(surname))
        {
            throw new ArgumentException("Must have a surname");
        }

        _firstName = firstName;
        _surname = surname;
    }

    public string Name 
    {
        get
        {
            return _firstName + " " + _surname;
        }
    }
}

이 클래스와 관련된 모든 테스트에서 나는 'IPerson'과 같은 인터페이스가 아닌 실제 인터페이스가 인스턴스화되고 사용되었습니다. 실제 테스트를 사용하면 테스트가 더욱 현실감있게됩니다 (매개 변수 검사와 'Name'속성의 실제 구현). 이와 같은 간단한 클래스의 경우 테스트 속도를 느리게하거나 결정적이거나 논리를 어지럽히 지 않습니다 (다른 클래스를 테스트 할 때 Name이 호출되었다는 것을 알 필요가 없습니다)-조롱 / 스터 빙.

이것에 대한 확장으로 사람들이 모의가 기대로 설정되는 테스트를 작성하는 것을 보았습니다. 그러면 모의가 테스트에서 직접 호출됩니다. 의심 할 여지없이 테스트는 항상 ... 음 ...


고맙게도 내가 사용한 프레임 워크는 구체적인 클래스를 모의 할 수 있었으므로 불편한 지점에서 인터페이스를 꺼내는 것은 문제가되지 않습니다.
Armand

5
그것은 문제를 바꾸지 않습니다-조롱 할 수있는 것에 대한 기술적 제약을 완화시키는 것을 사용하더라도 (예 : TypeMock과 같은 모의 프레임 워크 또는 동적 언어) 이러한 종류의 간단한 일은 조롱해서는 안됩니다.
FinnNk

경험상 데이터는 항상 행동이 아닌 행동을 위해 조롱하는 것이 었습니다.
ardave

10

분명하게 들릴지 모르지만 프로덕션 코드에서 모의 ​​객체를 사용하지 마십시오! 프로덕션 코드가 특정 모의 객체의 특성 ( MockHttpServletRequest예 : Springframework)에 의존하는 두 가지 이상의 예를 보았습니다 .


14
나는 당신의 거룩한 의무를 따르고 DailyWTF에 코드를 제출했으면 좋겠습니까?
keppla

1
이전 작업에서 우리는 코드베이스에서 DWTF로 아무것도 제출하지 못하도록 명시 적으로 금지되었습니다.
quant_dev 2016 년

9
@quant_dev : 그들이 그러한 정책을 가지고 있다는 사실은 개발자들에 대해 무서운 것을 암시합니다.
John Fisher

1
실제로는 아닙니다. 제품을 판매하기 위해 코드베이스를 신속하게 개발 한 다음, 제품이 성숙하고 초기 디자인이 부족하여 개발이 방해됨에 따라 기술 부채를 지불하기 위해 코드베이스를 통합하고 리팩토링하기 시작했습니다. 관리자는 이전 코드베이스가 똥이었고 시간과 자원을 리팩토링에 투자했지만 부정적인 홍보를 위험에 빠뜨리고 싶지 않았습니다.
quant_dev

바로 가기를 취하는 것만으로는 매일 wtf를 얻는 데 충분하지 않습니다 ...
poolie

9

제 생각에는 모의에 대한 과도한 메소드 호출 검사입니다. 필자는 이것이 EasyMock과 같은 몇 가지 조롱 프레임 워크에 의해 시행되는 관행이라고 생각합니다. 여기서 기본 모의 동작은 이전에 정확하게 지정되지 않은 추가 메소드 호출이있을 때마다 실패합니다. 이러한 종류의 엄격한 모의 방법 검사는 핵심 기능이 여전히 동일하더라도 코드를 조금만 변경해도 전체 테스트가 실패 할 수있는 취성 설계를 초래할 수 있습니다.

이에 대한 해결책은 모의 대신 스텁을 사용하기 시작했습니다. 이 주제에 대해 특히 깨달은 기사는 Mockito의 Javadoc에서 찾을 수 있습니다. http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html ( "2. 스터 빙은 어떻습니까?" ) 링크 : http://monkeyisland.pl/2008/07/12/should-i-worry-about-the-unexpected/ .

나는 Mockito와 함께 일하는 것을 즐겼습니다. 왜냐하면이 엄격한 조롱 행동을 강요하지 않고 대신 스텁을 사용했기 때문입니다. 또한 전체 모의 객체 대신 특정 메소드에 대한 메소드 검사를 시행합니다. 테스트 시나리오에서 실제로 중요한 메소드 만 확인하게됩니다.

여기에 몇 권의 책이 있으며이 주제와 조롱 및 일반적인 내용을 다루는 것이 좋습니다.

xUnit 패턴

단위 테스트 기술 : .Net의 예제

차세대 자바 테스트 : TestNG의 고급 개념 (이 책은 TestNG를에 대해 대부분이지만 좋은 장 조롱에 대해있다)


과도한 메소드 호출 검사 포인트에 +1 그러나 예기치 않은 메소드 호출로 인해 메소드에서 실패가 발생하는 코인의 반대쪽이 항상 있습니다. 고맙게도 Mockito는 Answer.RETURNS_SMART_NULLS이것을 진단하는 데 도움이되는 mock 설정을 가지고 있습니다.
Bringer128

4

내 경험에 반 패턴이 거의 관찰되지 않았습니다.

  • 상태 변경이 발생할 수 있고 확인해야하는 도메인 클래스가 조롱 / 교반됩니다.
  • 통합 테스트는 목업과 구체적인 클래스의 혼합과 상호 작용하여 통합 테스트의 목적을 무효화합니다.
  • 프로덕션 코드에서 실수로 mock 사용 (이것은 절대 일어나지 않아야 함)

그렇지 않으면 모의에 대한 나의 경험 특히 Mockito는 산들 바람이었습니다. 테스트를 작성하고 유지하기가 매우 쉬워졌습니다. GWT보기 / 발표자 상호 작용 테스트는 GWTTestCase보다 mock으로 훨씬 쉽습니다.


2 & 3은 확실한 문제입니다! (1)의 간단한 예를 얻었습니까?
Armand

2

여러 계층의 응용 프로그램에서 모의를 사용하는 테스트는 특히 해독 및 변경이 어렵다는 것을 알았습니다. 그러나 최근 개선 된 모의 프레임 워크 API (JMock을 사용하여 편리함)를 통해이 문제를 완화했다고 생각합니다.

5 년 또는 6 년 전 EasyMock과 같은 API는 강력하지만 매우 번거로 웠습니다. 종종 그것을 사용하는 테스트 코드는 테스트하는 코드보다 훨씬 복잡합니다. 그 당시에는 팀에 영향을 미치려고 노력했으며, 테스트를 위해 특별히 인터페이스를 대체로 구현 한 간단한 수제 모의를 사용했습니다.

최근에, 조롱 API가 더 읽기 쉬운 테스트를 만들기 때문에 이것에 대한 나의 강한 의견이 부드러워졌습니다. 본질적으로 나는 다른 개발자가 모호한 API 호출에 대한 유혹을 느끼지 않고 다른 개발자가 내 코드 (테스트 포함)를 변경할 수 있기를 원합니다.

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