program story

EasyMock : 무효 방법

inputbox 2020. 11. 8. 09:53
반응형

EasyMock : 무효 방법


테스트하려는 클래스의 종속성 인 클래스에서 void를 반환하는 메서드가 있습니다.

이 클래스는 거대하며 저는이 하나의 방법 만 사용하고 있습니다. 다른 작업을 수행하고이 메서드가받는 매개 변수에 액세스 할 수 있어야하므로 테스트를 위해이 메서드의 구현을 대체해야합니다.

EasyMock 에서이 작업을 수행하는 방법을 찾을 수 없습니다 . Mockito 를 사용하여 수행하는 방법을 알고 있다고 생각 doAnswer하지만 절대적으로 필요한 경우가 아니면 다른 라이브러리를 추가하고 싶지 않습니다.


올바르게 수행하려는 작업을 이해하면 다음을 사용할 수 있습니다 andAnswer().

mockObject.someMethod(eq(param1), eq(param2));
expectLastCall().andAnswer(new IAnswer() {
    public Object answer() {
        //supply your mock implementation here...
        SomeClass arg1 = (SomeClass) getCurrentArguments()[0];
        AnotherClass arg2 = (AnotherClass) getCurrentArguments()[1];
        arg1.doSomething(blah);
        //return the value to be returned by the method (null for void)
        return null;
    }
});

EasyMock에 사용자 가이드는 설명한다 :

반환 값 또는 예외 생성

때때로 우리는 모의 객체가 값을 반환하거나 실제 호출시 생성 된 예외를 던지기를 원합니다. 2.2 EasyMock에 있기 때문에, 목적에 의해 반환 expectLastCall()expect(T value)방법 제공 andAnswer(IAnswer answer)[사용자가 상기 인터페이스의 구현 지정할 수 IAnswer리턴 값 또는 예외를 생성하는데 사용된다.

IAnswer콜백 에서 모의 ​​호출에 전달 된 인수는 EasyMock.getCurrentArguments(). 이를 사용하는 경우 매개 변수 재정렬과 같은 리팩토링으로 인해 테스트가 중단 될 수 있습니다. 경고를 받았습니다.


호출 될 때마다 void 메서드를 호출 한 다음를 호출 EasyMock.expectLastCall()하기 전에 호출 replay()하면 Easymock은 각 호출을 "기억"합니다.

난 당신이 명시 적으로 호출 할 필요가 있다고 생각하지 않습니다 그래서 expect()(이외 lastCall당신은 그것의 호출을 제외하고는 무효 방법에서 아무것도 기대하지 않는 때문에).

고마워 크리스!

동료 StackOverflow 사용자 Burt Beckwith의 "Fun With EasyMock" 은 더 자세한 내용을 제공하는 좋은 블로그 게시물입니다. 주목할만한 발췌 :

기본적으로 내가 사용하는 흐름은 다음과 같습니다.

  1. 모의 만들기
  2. expect(mock.[method call]).andReturn([result])각 예상 호출에 대한 호출
  3. call mock.[method call], EasyMock.expectLastCall()각 예상 무효 호출에 대해
  4. replay(mock)"녹음"모드에서 "재생"모드로 전환하려면 호출
  5. 필요에 따라 모의를 주입
  6. 테스트 방법을 호출
  7. 전화 verify(mock)모든 예상 호출이 일어난 것을 보장하기 위해

나중에 매개 변수에 액세스하려는 경우 EasyMock 2.4에 새로 추가 된 Captures 클래스를 사용할 수도 있습니다 .

matcher 대신 "Capture"클래스의 인스턴스를 사용할 수 있습니다. 모의 메서드가 호출되면 Capture 인스턴스는 호출 된 매개 변수를 저장합니다.

Capture<ChartPanel> captured = new Capture<ChartPanel>();
// setChartPanel is going to be called during execution;
// we want to verify some things about the ChartPanel
// instance it's invoked with
chartMock.setChartPanel(capture(captured));
replay(chartMock);

ufdm.setChartAnnotater(chartMock);
// afterPropertiesSet triggers the setChartPanel call...
ufdm.afterPropertiesSet();
verify(chartMock);

// verify some things about the ChartPanel parameter our
// mock object was invoked with
assertSame(plot, captured.getValue().getChart().getPlot());

PowerMock을 확인하는 것이 좋습니다. EasyMock은 프록시 리플렉션 API를 기반으로합니다. 즉, 모든 것이 프록시이고 인터페이스 만 테스트 할 수 있으므로 최종 메서드와 클래스 만 테스트 할 수 있습니다. 이것은 일부에게는 효과가있을 수 있지만 세계를 구축 된대로 테스트하는 경우 더 많은 전력이 필요합니다.

With PowerMock the Java 5 instrumentation API removes the limitations. No need to write mock object implementations of the object to be tested (just ugly IMO). Couple PowerMock with Mockito (or JMockit) and you'll really be off to the races.

Of course, there is the other direction of rewriting your code to be more easily tested, which is generally a good idea too, if possible.


In situations like these I've found that making a nested class in my unit test class and overriding the methods with special requirements in that way is the best route. So if you're testing ClassA which has that method with the parameters you need to access, you'd do something like:

class MockClassA extends ClassA {
    @Override
    void specialMethod(String param1, String param2) {
        // do logging or manipulation of some sort
        super.specialMethod(param1,param2); // if you need to
    }
}

In my unit testing code, I then just use this instance instead. Just treat it as if it was any other mock object. Much easier than mixing libraries, which I agree is probably not a good idea.

참고URL : https://stackoverflow.com/questions/859031/easymock-void-methods

반응형