【问题标题】:Gradld Build - Use Mock Objects Created by Mockito for running unit testsGradld Build - 使用 Mockito 创建的模拟对象来运行单元测试
【发布时间】:2016-12-06 21:46:30
【问题描述】:

我有一个连接到外部 Web 服务的 Spring Boot 应用程序。该项目是使用 gradle 构建的。我在我的程序中嘲笑外部调用。当我在 STS 中作为 junit 测试运行时,测试运行成功。但是,当我进行“gradle build”时,测试失败了。当我查看日志时,我认为它失败了,因为测试正在命中实际服务而不是返回模拟对象。为了让我的 gradle 构建选择 mockito 生成的模拟对象作为测试的一部分,我需要做些什么吗?

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = ProxyApplication.class)
@WebAppConfiguration
public class ApplicationWrapperTest {

    @Mock
    private SoapClient soapClient;

    @InjectMocks
    @Autowired
    private ApplicationWrapper applicationWrapper;

    @Before
    public void init() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testDatesInApplication() throws Exception{
      //return mock object (webservice response) when soapClient is called
    }

ApplicationWrapper 代码

@Component
public class ApplicationWrapper {

    @Resource(name = "factory.soapClient")
    private SoapClientFactory soapClientFactory;

    @Autowired
    private JsonUtil jsonUtil;

    @Autowired
    private DomainUtil domainUtil;

    private static final String clientId = "soapClient";

    public String execute(String request, String apiName){
        Object req = domainUtil.createRequest(request, apiName);
        Object jaxbResponse = this.soapClientFactory.getClient(clientId).marshalSendAndReceive(req); 
        Object response = domainUtil.createResponse(jaxbResponse, apiName);
        return jsonUtil.toJsonString(response) ;
    }


  }

【问题讨论】:

  • 您能添加您的ProxyApplication 课程代码吗?它可能会覆盖您的模拟,并且由于 Gradle / Eclipse 类路径的差异,它仅在 Gradle 案例中被覆盖。
  • 嗨@adamr,ProxyApplication 类是一个SpringBoot Main 类,它存在许多组件扫描。有没有办法确保在构建过程中模拟始终优先?

标签: java spring gradle spring-boot mockito


【解决方案1】:

是的,您正在使用实际服务,因为您使用的是通过ProxyApplication.class 插入的 bean。问题是您混合了 2 种测试方法:Mockito 和 Spring。

要避免这些,您有多种选择:

  1. 在没有 SpringJUnit4ClassRunner.class 和 Spring 配置的情况下运行测试。删除@Autowired。使用MockitoJUnitRunner.class。这将是真正的单元测试

    @RunWith(MockitoJUnitRunner.class)
    public class ApplicationWrapperTest {
    
    @Mock
    private SoapClientFactory soapClientFactory;
    
    @Mock
    private SoapClient soapClient;
    
    @InjectMocks
    private ApplicationWrapper applicationWrapper;
    
    @Before
    public void init() {
        MockitoAnnotations.initMocks(this);
    }
    
    @Test
    public void testDatesInApplication() throws Exception{
      when(soapClientFactory.getClient(eq("yourclientid"))).thenReturn(soapClient);
      //return mock object (webservice response) when soapClient is called
    }
    
  2. 为您的 Spring 配置创建 spring 测试配置类,其中 soapClient 配置为 Mock。

【讨论】:

  • 您好 jny,我在 testDatesInApplication 方法中调用了 applicationWrapper.execute。这个方法有 2 个我想注入的自动装配的 bean。我只是想单独模拟外部调用。因此我使用了这两种方法。如果我删除 SpringJUnit4ClassRunner ,我会得到一个 NPE,因为没有注入 spring bean。当我结合这两种方法时,单元测试在 IDE 中可以正常工作,但在 gradle 构建期间却不行。
  • 哪个bean没有注入?你在使用 MockitoJUnitRunner.class 吗?
  • 是的,我最初尝试使用 MockitoJunitRunner 并遇到了这个问题。当我单独使用 MockitoJunitRunner 时,不会注入 bean。因此,我尝试同时使用 SpringJunit4ClassRunner 和 Mockito。
  • 我需要查看更多详细信息才能了解 bean 未连接的原因。正如我的示例中定义的那样,soapClient 应该被注入到 applicationWrapper 中。
  • 我已经粘贴了 applicationWrapper 代码。 DomainUtil 和 JSONUtil 没有被自动装配。
猜你喜欢
  • 1970-01-01
  • 2011-05-13
  • 1970-01-01
  • 2023-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-05
  • 1970-01-01
相关资源
最近更新 更多