java 模拟依赖项的Spring集成测试

nhhxz33t  于 2023-01-04  发布在  Java
关注(0)|答案(2)|浏览(126)

我使用的是Sping Boot 。我有一个Service类(注解为@Service),其中有一个注解为@Retryable的方法。
对于我的一个集成测试,我希望将Service bean加载到上下文(包括它的所有配置和注解)。
服务具有多个依赖项。例如,

@Service
@EnableRetry
public class MyService{
    private final BeanOne beanOne;
    private final BeanTwo beanTwo;

    public MyService(BeanOne beanOne, BeanTwo beanTwo){
        this.beanOne = beanOne;
        this.beanTwo = beanTwo
    }
    
    @Retryable(value = RuntimeException.class , maxAttempts = 3)
    public void serviceAction(){
        beanOne.doSomething();
        beanTwo.doSomething();
        doMoreThings();
    }

    private void doMoreThings(){
        //things
        //eventually throws Runtime Exception

    }
}

我想检查一下,我确实正确地实现了有关重试的所有内容。
我正在尝试编写Spring集成测试,模拟依赖bean,但仍然将MyService bean加载到上下文(以检查可重试项)。
我尝试模拟依赖bean(使用JUnit4和Mockito):

@Import({MyService.class})
@RunWith(SpringRunner.class)
public class MyServiceIntegrationTest{
    @Autowired
    private MyService myService;
    
    @MockBean
    private BeanOne beanOne;

    @MockBean
    private BeanTwo beanTwo;

    @Test
    public void test(){
        myService.serviceAction();
        verify(beanTwo,times(3)).doSomething();
    }
}

但是,我在beanOne.doSomething()调用中遇到了NullPointerException。**看起来MyServiceIntegrationTest类中的beanOne和beanTwo字段确实被模拟了,但是没有自动连接到实际的myService,而是myService的字段为空。**注意,@Retryable注解确实有效(并重复3次),但这是因为NullPointerException是一个RuntimeException。代码实际上从未到达doMoreThings()方法。

5lhxktic

5lhxktic1#

对于MyService的依赖项,尝试使用@SpyBean注解而不是@MockBean。@SpyBean注解将创建bean的spy并将其注入到应用程序上下文中,同时仍然允许使用Mockito来存根spy的方法。
例如:

@Import({MyService.class})
@RunWith(SpringRunner.class)
public class MyServiceIntegrationTest{
    @Autowired
    private MyService myService;
    
    @SpyBean
    private BeanOne beanOne;

    @SpyBean
    private BeanTwo beanTwo;

    @Test
    public void test(){
        myService.serviceAction();
        verify(beanTwo,times(3)).doSomething();
    }
}

这将允许您测试MyService类及其依赖项,同时仍然使用应用程序上下文中的实际MyService示例。

soat7uwm

soat7uwm2#

@Import用于加载配置,您应该使用@SpringApplicationConfiguration,或者更好的是更新的@SpringBootTest注解。顺便说一下,@SpringApplicationConfiguration当前已被弃用。
示例:

@SpringBootTest(classes = {MyService.class}) // or @SpringApplicationConfiguration with the same paramters
@RunWith(SpringRunner.class)
public class MyServiceIntegrationTest{
    @Autowired
    private MyService myService;
    
    @MockBean
    private BeanOne beanOne;

    @MockBean
    private BeanTwo beanTwo;

    @Test
    public void test(){
        myService.serviceAction();
        verify(beanTwo,times(3)).doSomething();
    }
}

检查:

相关问题