通过注释类创建带有限定符的@MockBean?

时间:2019-02-06 07:21:29

标签: java spring-boot spring-test spring-bean

在Spring Boot测试中,我使用2个具有不同限定符的模拟bean:

@RunWith(SpringRunner.class)
@SpringBootTest
class HohoTest {
    @MockBean @Qualifier("haha") IHaha ahaha;
    @MockBean @Qualifier("hoho") IHaha ohoho;
}

由于我没有明确使用这些bean,所以我宁愿将它们从类主体中移开,因为@MockBean注释现在可以重复使用:

@RunWith(SpringRunner.class)
@SpringBootTest
@MockBean(IHaha.class)
@MockBean(IHaha.class)
class HohoTest {}

但是,我也需要传递一个限定符,因为它们具有相同的类型。关于如何实现这一目标的任何想法吗?

4 个答案:

答案 0 :(得分:2)

因为使用注解 @Qualifier 意味着按名称选择 bean,因此您可以使用如下代码为模拟设置名称:

@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {JsonMapperConfig.class})
public class IntegrationFlowTest {

    @MockBean(name = "s3MessageRepository")
    private S3Repository s3MessageRepository;

// etc

答案 1 :(得分:1)

在课程级别声明@MockBean时,当前不支持提供限定符

如果您希望获得这种支持,建议您request it in the Spring Boot issue tracker

否则,您将需要在@MockBean旁边的字段上继续声明@Qualifier

答案 2 :(得分:1)

如果可以将模拟定义完全移出测试类,则还可以在单​​独的@Configuration类中创建模拟:

@Configuration
public class MockConfiguration
{
    @Bean @Qualifier("haha")
    public IHaha ahaha() {
        return Mockito.mock(IHaha.class);
    }
    @Bean @Qualifier("hoho")
    public IHaha ohoho() {
        return Mockito.mock(IHaha.class);
    }
}

答案 3 :(得分:1)

我对注入带有 @Order 批注的模拟服务bean有类似的要求。我还需要验证服务功能的调用计数。下面是我的实现。这可能会帮助某人。

import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class ServiceNameTest {

  @Autowired private ServiceName serviceName;

  // Important: Used to reset interaction count of our static 
  // bean objects before every test.
  @Before
  public void reset_mockito_interactions() {
    Mockito.clearInvocations(MockServicesConfig.bean1);
    Mockito.clearInvocations(MockServicesConfig.bean2);
  }

  @Configuration
  public static class MockServicesConfig {

    public static InterfaceName bean1;
    public static InterfaceName bean2;

    @Bean
    @Order(1)
    public InterfaceName bean1() {
      bean1 = Mockito.mock(InterfaceName.class);
      // Common when() stubbing
      return bean1;
    }

    @Bean
    @Order(2)
    public InterfaceName vmpAdapter() {
      bean2 = Mockito.mock(InterfaceName.class);
      // Common when() stubbing
      return bean2;
    }
  }


  @Test
  public void test_functionName_mock_invocation1() {

    // Arrange --> Act --> Assert

    // nullify other functions custom when() stub.
    // updating this functions custom when() stub.

    verify(MockServicesConfig.bean1, times(1)).functionName("");
  }

  @Test
  public void test_functionName_mock_invocation2() {

    // Arrange --> Act --> Assert

    // nullify other functions custom when() stub.
    // updating this functions custom when() stub.

    verify(MockServicesConfig.bean1, times(1)).functionName("");
  }


}