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模拟该方法的行为。而这个方法本身需要另外写一个测试方法。