有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Mockito ArgumentCaptor不在catch块中捕获argurment

我写了这篇文章

public class FirstService {

    private final SecondService secondService;

    public FirstService(SecondService secondService) {
        this.secondService = secondService;
    }

    public void hz() throws Exception {
        try {
            methodThrowsException();
        } catch (Exception e){
            secondService.handleErrorMessage(e.getMessage());
            throw e;
        }
    }

    private void methodThrowsException() throws Exception {
        throw new Exception("message");
    }
}

这项服务:

public class SecondService {
    public void handleErrorMessage(String message) {}
}

我需要验证是否调用了handleErrorMessage。我写了一个测试:

import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;

import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

public class FirstServiceTest {
    private FirstService firstService;
    private SecondService secondService;

    @Before
    public void setUp() {
        secondService = mock(SecondService.class);
        firstService = new FirstService(secondService);
    }

    @Test(expected = Exception.class)
    public void hz() throws Exception {
        firstService.hz();
        ArgumentCaptor<String> argumentCaptor = ArgumentCaptor.forClass(String.class);
        verify(secondService).handleErrorMessage(argumentCaptor.capture());
        String value = argumentCaptor.getValue();

        assertEquals("message", value);
    }
}

通过测试。但如果我改变assertEquals("message666", value);,它仍然会通过。如果我没有在catch block中抛出异常,ArgumentCaptor将捕获参数,但当我抛出异常时,它不起作用


共 (1) 个答案

  1. # 1 楼答案

    您的测试带有注释: @Test(expected = Exception.class)

    这意味着,如果Exception(或的任何子类)达到顶层,测试将通过。这发生在测试的第一行:

        firstService.hz();
    

    这就是它过去的原因。不幸的是,该异常意味着测试的其余部分永远不会运行,因为该异常会传播到测试方法之外

    有点难看,但这段代码符合您的要求:

        @Test
        public void hz() throws Exception {
    
            try {
                firstService.hz();
    
                // If we get here, then we didn't throw an exception - fail
                Assert.fail();
            } catch (Exception ex) {
                // Exception was expected - disregard and continue
                // no-op
            }
            ArgumentCaptor<String> argumentCaptor = ArgumentCaptor.forClass(String.class);
            verify(secondService).handleErrorMessage(argumentCaptor.capture());
            String value = argumentCaptor.getValue();
    
            assertEquals("message", value);
        }
    

    上面的方法运行您的方法,并捕获异常(如果没有获得预期的异常,则会失败)。然后,它继续进行,并运行剩下的测试

    JUnit 5提供了一种稍微干净的方法,但您必须迁移:

        @Test
        public void hz() throws Exception {
    
            Assertions.assertThrows(Exception.class, () -> firstService.hz());
    
            ArgumentCaptor<String> argumentCaptor = ArgumentCaptor.forClass(String.class);
            verify(secondService).handleErrorMessage(argumentCaptor.capture());
            String value = argumentCaptor.getValue();
    
            assertEquals("asdf", value);
        }