최종 방법 조롱
mockito를 사용하여 최종 방법으로 일부 클래스를 모의해야합니다. 나는 이와 같은 것을 썼다
@Test
public void test() {
B b = mock(B.class);
doReturn("bar called").when(b).bar();
assertEquals("must be \"overrided\"", "bar called", b.bar());
//bla-bla
}
class B {
public final String bar() {
return "fail";
}
}
그러나 그것은 실패합니다. 나는 약간의 "해킹"을 시도했고 그것은 작동한다.
@Test
public void hackTest() {
class NewB extends B {
public String barForTest() {
return bar();
}
}
NewB b = mock(NewB.class);
doReturn("bar called").when(b).barForTest();
assertEquals("must be \"overrided\"", "bar called", b.barForTest());
}
작동하지만 "냄새".
그렇다면 올바른 방법은 어디입니까?
감사.
Mockito에서는 최종 메소드를 조롱하는 기능이 지원되지 않습니다.
Jon Skeet이 언급했듯이 최종 방법에 대한 종속성을 피할 수있는 방법을 찾아야합니다. 즉, 바이트 코드 조작 (예 : PowerMock 사용)을 통한 몇 가지 방법이 있습니다.
Mockito 및 PowerMock의 비교는 구체적으로 일을 설명 할 것이다.
로부터 Mockito 자주 묻는 질문 :
Mockito의 한계는 무엇입니까
- 최종 메서드를 모의 할 수 없습니다. 실제 동작은 예외없이 실행됩니다. Mockito는 최종 방법을 조롱하는 것에 대해 경고 할 수 없으므로주의해야합니다.
Powermock을 Mockito와 함께 사용할 수 있으며 B.class를 하위 클래스화할 필요가 없습니다. 이것을 테스트 클래스의 맨 위에 추가하십시오.
@RunWith(PowerMockRunner.class)
@PrepareForTest(B.class)
@PrepareForTest
Powermock이 최종 및 정적 메서드를 모의 할 수 있도록 B.class를 계측하도록 지시합니다. 이 접근 방식의 단점은 Spring 테스트 실행기와 같은 다른 테스트 실행기를 사용할 수 없도록하는 PowerMockRunner를 사용해야한다는 것입니다.
Mockito 2는 이제 최종 방법을 조롱하는 것을 지원하지만 이것은 "인큐베이팅"기능입니다. 활성화하려면 여기에 설명 된 몇 가지 단계가 필요합니다. https://github.com/mockito/mockito/wiki/What's-new-in-Mockito-2#mock-the-unmockable-opt-in-mocking-of- 최종 수업 방법
Mockito 2.x는 이제 최종 메서드 및 최종 클래스 스터 빙을 지원합니다.
문서에서 :
Mocking of final classes and methods is an incubating, opt-in feature. This feature has to be explicitly activated by creating the file
src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
containing a single line:
mock-maker-inline
After you create this file you can do:
final class FinalClass { final String finalMethod() { return "something"; } } FinalClass concrete = new FinalClass(); FinalClass mock = mock(FinalClass.class); given(mock.finalMethod()).willReturn("not anymore"); assertThat(mock.finalMethod()).isNotEqualTo(concrete.finalMethod());
In subsequent milestones, the team will bring a programmatic way of using this feature. We will identify and provide support for all unmockable scenarios.
Assuming that B class is as below:
class B {
private String barValue;
public final String bar() {
return barValue;
}
public void final setBar(String barValue) {
this.barValue = barValue;
}
}
There is a better way to do this without using PowerMockito framework. You can create a SPY for your class and can mock your final method. Below is the way to do it:
@Test
public void test() {
B b = new B();
b.setBar("bar called") //This should the expected output:final_method_bar()
B spyB = Mockito.spy(b);
assertEquals("bar called", spyB.bar());
}
I just did this same thing. My case was that I wanted to ensure the method didn't "Cause" an error but since it's a catch/log/return method I couldn't test for it directly without modifying the class.
I wanted to simply mock the logger I passed in, but something about mocking the "Log" interface didn't seem to work and Mocking a class like "SimpleLog" didn't work because those methods are final.
I ended up creating an anonymous inner class extending SimpleLog that overrid the base-level "log(level, string, error)" method that the others all delegate to, then just waiting for a call with a "level" of 5.
In general, extending a class for behavior isn't really a bad idea, might be preferable to mocking anyway if it's not too complicated.
참고URL : https://stackoverflow.com/questions/3793791/final-method-mocking
'programing' 카테고리의 다른 글
log4j를 콘솔에 쓰는 방법 (0) | 2020.12.08 |
---|---|
스크립트 실행 후 그놈 터미널 닫기를 피합니까? (0) | 2020.12.08 |
확인란이 선택되어 있는지 어떻게 확인합니까? (0) | 2020.12.08 |
Java를 사용하여 PDF 파일을 읽는 방법은 무엇입니까? (0) | 2020.12.08 |
UIPageViewController 내의 슬라이딩 페이지 위에 UIPageControl 요소를 배치하는 방법은 무엇입니까? (0) | 2020.12.07 |