Pertanyaan Cara menguji pemanggilan metode di dalam kelas anonim menggunakan mockito


@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");

                }
            }
        }       
    }

Ini adalah kode contoh yang ingin saya uji. Saya tidak dapat menemukan banyak pengujian kelas anonim di internet. Saya ingin menguji metode exe (), buka metode newTransactionTemplate.execute dan tirukan panggilan ke reserveService.callReserve (reserveDetails).

Bisakah badan menyarankan bagaimana saya bisa menguji situasi ini?

di sini adalah contoh bagaimana saya mencoba menguji:

 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());

    }

Panggilan kedua saat (mockTransactionTemplate.execute .. dengan rilis objek kembaliInfo melempar java.lang.ClassCastException:


5
2018-05-05 03:08


asal


Jawaban:


Berikut ini adalah solusi untuk skenario yang disebutkan di atas. Karena saya tidak tertarik untuk menguji doa newTransactionTemplate.execute (), itu menjadi API musim semi. Saya ingin menguji doa dari reserveService.callReserve (reserveDetails) dan reserveService.callRelease (id). Satu-satunya cara untuk menguji ini adalah jika kita membuat implementasi / substitusi transaksi "nyata" / rintisan yang hanya lewat saja. jadi metode doIntransaction seharusnya tidak melakukan apa-apa selain mengeksekusi aksi. maka kita dapat mengatur ekspektasi pada metode aksi yang dalam hal ini adalah 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)); 

7
2018-05-07 19:17



Dimana reserveService berasal dari? Jika Anda menyuntikkannya melalui keduanya SomeClassKonstruktor atau setter, Anda bisa lulus tiruan sebagai gantinya.

// 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);

1
2018-05-05 03:15