SpringBoot中单元测试如何对包含AopContext.currentProxy()的方法进行测试

今天在工作中遇到一个问题,一个Service类中有一个方法,其中使用了 AopContext.currentProxy() 去访问自身的函数,例如

int result = ((OrderServiceImpl) AopContext.currentProxy()).save();

单元测试方法如下:

@InjectMocks
private OrderServiceImpl orderServiceUnderTest;

@Test
@DisplayName("AopContext测试")
public void test() {
    int result = orderServiceUnderTest.insertDemo();
    assertThat(result).isEqualTo(1);
}

但是在运行测试的时候出现了 java.lang.IllegalStateException: Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available, and ensure that AopContext.currentProxy() is invoked in the same thread as the AOP invocation context.

这时候需要将AopContext的静态方法也mock,同时,需要将被测类 OrderServiceImpl 再注入一次,注入到AopContext中。

具体代码如下:

public class SpringTestDemoApplicationTests {
    @InjectMocks
    private OrderServiceImpl orderServiceUnderTest;

    @Spy
    private orderServiceImpl orderServiceMock;

    @Mock
    private MockedStatic<AopContext> aopContextMockedStatic;

    @BeforeEach
    public void setup() {
        openMocks(this);
        aopContextMockedStatic.when(AopContext::currentProxy).thenReturn(orderServiceMock);
    }

    @Test
    @DisplayName("AopContext测试")
    public void test() {
        int result = orderServiceUnderTest.insertOrder();
        assertThat(result).isEqualTo(1);
    }

    @AfterEach
    public void tearDown() {
        aopContextMockedStatic.close();
    }
}

如果proxy对象调用的方法是通过@Autowired注解注入的对象,可能会出现NPE。此时需要将proxy对象的注解由@Spy 改成 @Mock,并通过mockito模拟该方法的行为。而这个方法本身需要另外写一个测试方法。

posted @ 2023-05-11 23:05  飞鸟_Asuka  阅读(745)  评论(0编辑  收藏  举报