【问题标题】:MockBean doesn't work in Spring boot integration testMockBean 在 Spring Boot 集成测试中不起作用
【发布时间】:2019-08-10 22:19:32
【问题描述】:

我有 Spring Integration 测试,我试图模拟我的一些 Bean。出于某种原因,尽管我嘲笑了他们,但他们是 NULL。这是代码sn-p:

我想模拟的 Bean

@Component
public class MockWS {

    public String callSoapClient() throws JAXBException{
        return "CallSoapCl";
    }
}

使用 Bean 的类

public class SmDpES2PortImpl implements ES2SmDp {
    @Autowired
    private MockWS mock;

    @Override
    public void es2DownloadProfile(ES2DownloadProfileRequest parameters) {
         try {
            LOG.info("\n\n\n TEST BEAN: " + mock.callSoapClient() + "\n\n");
          }
     }  
}

已模拟 Bean 的 Spring Boot 集成测试

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class ES2SmDpApplicationTests {

    @MockBean(name="mockWS")
    MockWS mockService;

    @Test
    public void test1Es2DownloadProfile_Sucess() throws MalformedURLException, JAXBException, SOAPException {
        when(mockService.callSoapClient()).thenReturn("CallMockCLient");
    }
}

构建执行的输出:TEST BEAN: null

【问题讨论】:

    标签: java spring-boot mocking


    【解决方案1】:

    在我的例子中,以下注释组合起作用:

    @RunWith(SpringRunner.class) 
    @SpringBootTest(classes = { ControllerThatIAmTesting.class }) 
    @AutoConfigureMockMvc(addFilters = false) // if using MockMvc object
    

    但是我必须在带有@MockBean 注释的测试类中显式声明我在 ControllerThatIAmTesting 中使用的两个 Autowired 对象 - 否则 Spring 会抱怨它找不到合适的实现 - 顺便说一下,我的接口和它们的实现都在同一个对应包

    此外,使用 @WebMvcTest 而不是 @SpringBootTest(其他建议将其作为更具体的场景)导致 Spring 无法从我的 @Configuration 类中找到并初始化其他一些 @Autowired 依赖项。

    相关帖子post1post2post3

    【讨论】:

      【解决方案2】:

      你应该模拟一个接口,而不是一个类。此外,SmDpES2PortImpl 必须是 Spring bean。请尝试以下操作:

      界面:

      public interface IMockWS {
      
          public String callSoapClient() throws JAXBException;
      }
      

      组件类:

      @Component
      public class MockWS implements IMockWS {
      
          @Override
          public String callSoapClient() throws JAXBException{
              return "CallSoapCl";
          }
      }
      

      服务类:

      @Service //Also @Component is a good alternative
      public class SmDpES2PortImpl implements ES2SmDp {
          @Autowired
          private IMockWS mock; //Notice that you are wiring an interface
      
          @Override
          public void es2DownloadProfile(ES2DownloadProfileRequest parameters) {
               try {
                  LOG.info("\n\n\n TEST BEAN: " + mock.callSoapClient() + "\n\n");
                }
           }  
      }
      

      测试类:

      @RunWith(SpringRunner.class)
      @SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT)
      @FixMethodOrder(MethodSorters.NAME_ASCENDING)
      public class ES2SmDpApplicationTests {
      
          @MockBean
          IMockWS mockService; //Again, you are mocking the interface, not the implementing class
      
          @Test
          public void test1Es2DownloadProfile_Sucess() throws MalformedURLException, JAXBException, SOAPException {
              when(mockService.callSoapClient()).thenReturn("CallMockCLient");
          }
      }
      

      【讨论】:

      • 感谢您的分享。我完全按照你写的那样做,但对象仍然是空的。看起来问题可能是由其他原因引起的 - Spring 或其他原因。
      • 你还在用@MockBean(name="mockWS")吗?我认为您不需要给出 bean 的名称。另外,也许您必须检查@SpringBootApplication 注释的位置,也许您的组件扫描有问题。
      • 我从@MockBean @MockBean IMockWS mockService; 中删除了名称。关于@SpringBootApplication,它位于包的根目录
      猜你喜欢
      • 2017-04-15
      • 1970-01-01
      • 2018-07-27
      • 2022-08-21
      • 1970-01-01
      • 2017-01-05
      • 2018-01-01
      • 2021-04-05
      • 2020-02-25
      相关资源
      最近更新 更多