Как проверить вызов метода внутри анонимного класса с помощью mockito - PullRequest
6 голосов
/ 05 мая 2011
@Transactional(propagation = Propagation.REQUIRED)
    public void exe() {
        try {
            Reserve reserveInfo = newTransactionTemplate.execute(new TransactionCallback<Reserve>() {
                @Override
                public Reserve doInTransaction(TransactionStatus status) {
                    return reserveService.callReserve(reserveDetails);
                }
            });
            if(reserveInfo != null && reserveInfo.getStatus()=="DONE") {
            someOtherService.doSomething();
            }
        } finally {
            if(reserveInfo!= null && reserveInfo.getStatus().equals("DONE")){
                final String id = reserveInfo.getId();                                  
                Release releaseInfo = newTransactionTemplate.execute(new TransactionCallback<Release>() {
                    @Override
                    public Release doInTransaction(TransactionStatus status) {
                        return reserveService.callRelease(id);
                    }
                });             
                if (releaseInfo.getStatus() != "RELEASED") {
                    throw new RuntimeException("Problem in releaseing");

                }
            }
        }       
    }

Это пример кода, который я хочу проверить.Я не мог найти много на тестировании анонимного класса в сети.Я хочу протестировать метод exe (), пройти через метод newTransactionTemplate.execute и смоделировать вызов reserveService.callReserve (reserveDetails).

Может ли кто-нибудь предложить, как я могу проверить эту ситуацию?

вот пример того, как я пытаюсь проверить:

 private SomeService someService = null;
    @Mock
    private ReserveService mockReserveService;
    @Mock
    private ReleaseService mockReleaseService;
    @Mock
    private TransactionTemplate mockTransactionTemplate;
    @Mock
    private SomeOtherService mockSomeOtherService;    
    @BeforeMethod
    public void setup() throws Exception {
       MockitoAnnotations.initMocks(this);   
       someService = new SomeService();
       someService.setReserveService(mockReserveService);
       someService.setReleaseService(mockReleaseService);
       someService.setSomeOtherService(mockSomeOtherService);
       someService.setNewTransactionTemplate(mockTransactionTemplate);
    }
    @Test(enabled=true)
    public void exeHappyPath() {
        Reserve reserveInfo = new Reserve();
        reserveInfo.setId("123");
        reserveInfo.setStatus("DONE");
        Release releaseInfo = new Release();
        releaseInfo.setStatus("RELEASED");
        when(mockReserveService.callReserve(Mockito.any(ReserveDetails.class))).thenReturn(reserveInfo);
        when(mockReserveService.callRelease(reserveInfo.getId())).thenReturn(releaseInfo);
        when(mockTransactionTemplate.execute(Mockito.<TransactionCallback<Reserve>>any())).thenReturn(reserveInfo);
        when(mockTransactionTemplate.execute(Mockito.<TransactionCallback<ReleaseInfo>>any())).thenReturn(releaseInfo);
        //Call the exe method
        someService.exe();

        verify(mockReserveService, times(1)).callReserve(Mockito.any(ReserveDetails.class));
        verify(mockReserveService, times(1)).callRelease(reserveInfo.getId())); 
        verify(mockSomeOtherService, times(1)).doSomthing());

    }

Второй вызов when (mockTransactionTemplate.execute .. с возвращаемым объектом releaseInfo выдает java.lang.ClassCastException:

Ответы [ 2 ]

8 голосов
/ 07 мая 2011

Вот решение вышеупомянутого сценария. Поскольку я не был заинтересован в тестировании вызова newTransactionTemplate.execute () , это был весенний API. Я хотел протестировать вызов ReserveService.callReserve (ReserveDetails) и ReserveService.callRelease (id) . Единственный способ проверить это, если мы создадим «реальную» реализацию / заглушку транзакции шаблон / транзакция, которая просто проходит через. поэтому метод doIntransaction не должен делать ничего, кроме выполнения действия. тогда мы можем установить ожидание для методов действия, которые в этом случае являются ReserveService .

    when(mockTransactionTemplate.execute(Mockito.<TransactionCallback>any())).thenAnswer(new Answer() {
         public Object answer(InvocationOnMock invocation) {
             Object[] args = invocation.getArguments();
           TransactionCallback arg = (TransactionCallback)args[0];
             return arg.doInTransaction(new SimpleTransactionStatus());
         }
     });     
    when(mockResourceService.callReserve(any(ReserveDetails.class))).thenReturn(reserveInfo);
    when(mockResourceService.callRelease(eq(id))).thenReturn(releaseInfo);

    //Call the exe method
    someService.exe();

    verify(mockResourceService, times(1)).callReserve(any(ReserveDetails.class));
    verify(mockSomeOtherService, times(1)).doSomthing());
    verify(mockMemberResourceService, times(1)).callRelease(eq(id)); 
1 голос
/ 05 мая 2011

Откуда берется reserveService? Если вы вводите его через конструктор SomeClass или сеттер, вы можете вместо этого передать макет.

// Set up your mock and stub out the method call
ReserveService reserveService = mock(ReserveService.class);
when(reserveService.callReserve(any(ReserveDetails.class))).thenReturn(null);

// Inject, either via constructor or setter
SomeClass instance = new SomeClass(reserveService);
// Or, instance.setReserveService(reserveService);
...