programing

주입된 모의 객체의 메서드에 전달된 인수를 Mockito가 캡처하는 방법은 무엇입니까?

coolbiz 2023. 7. 29. 13:06
반응형

주입된 모의 객체의 메서드에 전달된 인수를 Mockito가 캡처하는 방법은 무엇입니까?

Spring AMQP 연결 개체를 내부적으로 사용하는 서비스 클래스를 테스트하려고 합니다.이 연결 개체는 Spring에 의해 주입됩니다.하지만 저는 제 유닛 테스트가 실제로 AMQP 브로커와 통신하는 것을 원하지 않기 때문에 Mock을 사용하여 연결 객체의 모의를 주입하고 있습니다.

/** 
 * The real service class being tested.  Has an injected dependency. 
 */ 
public class UserService {

   @Autowired
   private AmqpTemplate amqpTemplate;

   public final String doSomething(final String inputString) {
      final String requestId = UUID.randomUUID().toString();
      final Message message = ...;
      amqpTemplate.send(requestId, message);
      return requestId;
   }
}

/** 
 * Unit test 
 */
public class UserServiceTest {

   /** This is the class whose real code I want to test */
   @InjectMocks
   private UserService userService;

   /** This is a dependency of the real class, that I wish to override with a mock */
   @Mock
   private AmqpTemplate amqpTemplateMock;

   @Before
   public void initMocks() {
      MockitoAnnotations.initMocks(this);
   }

   @Test
   public void testDoSomething() {
      doNothing().when(amqpTemplateMock).send(anyString(), any(Message.class));

      // Call the real service class method, which internally will make 
      // use of the mock (I've verified that this works right).
      userService.doSomething(...);

      // Okay, now I need to verify that UUID string returned by 
      // "userService.doSomething(...) matches the argument that method 
      // internally passed to "amqpTemplateMock.send(...)".  Up here 
      // at the unit test level, how can I capture the arguments passed 
      // to that inject mock for comparison?
      //
      // Since the value being compared is a UUID string created 
      // internally within "userService", I cannot just verify against 
      // a fixed expected value.  The UUID will by definition always be
      // unique.
   }
}

이 코드 샘플의 코멘트가 질문을 명확하게 제시하기를 바랍니다.Mockito가 실제 클래스에 모의 종속성을 주입하고 실제 클래스에 대한 단위 테스트가 모의에 호출을 하게 할 때, 주입된 모의에 전달된 정확한 주장을 나중에 어떻게 검색할 수 있습니까?

하나 이상을 사용합니다.ArgumentCaptors.

당신의 유형이 무엇인지는 분명하지 않지만, 어쨌든.방법이 있는 모의 실험이 있다고 가정해 보겠습니다.doSomething()테이크 어Foo인수로 다음을 수행합니다.

final ArgumentCaptor<Foo> captor = ArgumentCaptor.forClass(Foo.class);

verify(mock).doSomething(captor.capture());

final Foo argument = captor.getValue();

// Test the argument

또한 메소드가 void를 반환하고 아무 작업도 수행하지 않는 것으로 보입니다.다음과 같이 적으십시오.

doNothing().when(theMock).doSomething(any());

걸 수 있습니다doAnswer()끝까지send()에 대한 방법.amqpTemplateMock그런 다음 의 호출 인수를 캡처합니다.AmqpTemplate.send().

첫 번째 줄 만들기testDoSomething()이러이러한

    Mockito.doAnswer(new Answer<Void>() {
          @Override
          public Void answer(final InvocationOnMock invocation) {
            final Object[] args = invocation.getArguments();
            System.out.println("UUID=" + args[0]);  // do your assertions here
            return null;
          }
    }).when(amqpTemplateMock).send(Matchers.anyString(), Matchers.anyObject());

모든 것을 종합하면, 시험은

import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

public class UserServiceTest {

  /** This is the class whose real code I want to test */
  @InjectMocks
  private UserService userService;

  /** This is a dependency of the real class, that I wish to override with a mock */
  @Mock
  private AmqpTemplate amqpTemplateMock;

  @Before
  public void initMocks() {
    MockitoAnnotations.initMocks(this);
  }

  @Test
  public void testDoSomething() throws Exception {
    Mockito.doAnswer(new Answer<Void>() {
      @Override
      public Void answer(final InvocationOnMock invocation) {
        final Object[] args = invocation.getArguments();
        System.out.println("UUID=" + args[0]);  // do your assertions here
        return null;
      }
    }).when(amqpTemplateMock).send(Matchers.anyString(), Matchers.anyObject());
    userService.doSomething(Long.toString(System.currentTimeMillis()));
  }
}

이것은 출력을 제공합니다.

UUID=8e276a73-12fa-4a7e-a7cc-488d1ce0291f

모키토로 모키토를 이용한 모키토 보이드 방법을 만드는 방법이라는 글을 읽고 알게 되었습니다.

언급URL : https://stackoverflow.com/questions/29169759/how-can-mockito-capture-arguments-passed-to-an-injected-mock-objects-methods

반응형