programing

@InjectMocks 클래스의 메서드를 조롱하려면 어떻게 해야 합니까?

shortcode 2022. 11. 24. 20:53
반응형

@InjectMocks 클래스의 메서드를 조롱하려면 어떻게 해야 합니까?

예를 들어 핸들러가 있습니다.

@Component
public class MyHandler {

  @AutoWired
  private MyDependency myDependency;

  public int someMethod() {
    ...
    return anotherMethod();
  }

  public int anotherMethod() {...}
}

이렇게 쓰고 싶어요.

@RunWith(MockitoJUnitRunner.class}
class MyHandlerTest {

  @InjectMocks
  private MyHandler myHandler;

  @Mock
  private MyDependency myDependency;

  @Test
  public void testSomeMethod() {
    when(myHandler.anotherMethod()).thenReturn(1);
    assertEquals(myHandler.someMethod() == 1);
  }
}

하지만 실제로는anotherMethod()비웃으려고 할 때마다요.어떻게 하면 좋을까요?myHandler그 방법을 조롱할 수 있을까?

우선 MyHandler 메서드를 조롱하는 이유는 다음과 같습니다.이미 테스트하고 있습니다.anotherMethod()복잡한 논리를 가지고 있는데 왜 다시 테스트해야 합니까?someMethod()할 수 있다면verify뭐라고 부르죠?
다음을 통해 수행할 수 있습니다.

@RunWith(MockitoJUnitRunner.class)
class MyHandlerTest {

  @Spy  
  @InjectMocks  
  private MyHandler myHandler;  

  @Mock  
  private MyDependency myDependency;  

  @Test  
  public void testSomeMethod() {  
    doReturn(1).when(myHandler).anotherMethod();  
    assertEquals(myHandler.someMethod() == 1);  
    verify(myHandler, times(1)).anotherMethod();  
  }  
}  

주의: '스파이' 오브젝트의 경우 사용해야 합니다.doReturn대신thenReturn(자세한 설명은 이쪽)

위의 모든 답변은 매우 좋고 유용할 수 있으므로, 제 글을 계속 읽기 전에 먼저 이러한 원칙들을 공부하고 이해하시기 바랍니다.

내 시나리오에서는 위의 조언 중 어떤 것도 효과가 없었다.디버깅을 오래 한 후에 도움이 된 글을 올리도록 하겠습니다.

테스트된 클래스에서 메서드를 호출하려면@Spy주석과 함께 필요@InjectMocks(또는Mockito.spy(XXX)콜 또는 코스)

흥미로운 부분은 이러한 주석의 순서가 중요하다는 것입니다!@Spy주석은 앞에 와야 합니다. @InjectMocks주석입니다.

동작하지 않는다

...

@InjectMocks
@Spy
private TestedObject instance

...

동작할 것이다

...

@Spy
@InjectMocks
private TestedObject instance

...

당신의 코드에서 당신은 MyHandler를 전혀 테스트하지 않고 있습니다.테스트하는 것을 비웃는 것이 아니라 실제 방법이라고 부르고 싶은 것입니다.만약 마이핸들러가 의존관계가 있다면, 당신은 그들을 조롱할 것이다.

다음과 같은 경우:

public interface MyDependency {
  public int otherMethod();
}

public class MyHandler {
  @AutoWired
  private MyDependency myDependency;

  public void someMethod() {
    myDependency.otherMethod();
  }
}

테스트 중:

private MyDependency mockDependency;
private MyHandler realHandler;

@Before
public void setup() {
   mockDependency = Mockito.mock(MyDependency.class);
   realHandler = new MyHandler();
   realhandler.setDependency(mockDependency); //but you might Springify this 
}

@Test
public void testSomeMethod() {

  //specify behaviour of mock
  when(mockDependency.otherMethod()).thenReturn(1);

  //really call the method under test
  realHandler.someMethod();
}

요점은 테스트 대상 메서드를 실제로 호출하는 것이지만, 그들이 가질 수 있는 의존관계를 조롱하는 것이다(예를 들어 다른 클래스의 호출 메서드).

다른 클래스가 어플리케이션의 일부일 경우 유닛테스트를 실시합니다.

주의: 위의 코드는 주석을 더 많이 붙이면 짧아질 수 있지만, 설명을 위해 좀 더 명확하게 하고 싶었습니다(또, 주석이 무엇인지도 기억나지 않습니다.

언급URL : https://stackoverflow.com/questions/30774358/how-can-i-mock-methods-of-injectmocks-class

반응형