繁体   English   中英

Spock + Spring - 从 Stubbed @SpringBean 返回的存根始终返回 null

[英]Spock + Spring - Stubs returned from Stubbed @SpringBean always return null

我正在尝试使用 Spock 围绕 Spring 应用程序创建集成测试。 由于它不是 Spring Boot 应用程序,并且@SpringBootTest注释严重干扰了应用程序的初始化,因此我使用的是最小配置。

我特别需要在我的应用程序中存根一个返回Message类型对象的服务; 在实际应用程序中,这些对象将来自第三方供应商的库,它们不能被实例化或子类化,它们的成员也没有设置器,所以我唯一的选择是为它们创建Stub 但是,使用这种当前配置(我已经大大简化了测试,只是为了了解要点):

@ContextConfiguration([TestSetup]) // supplies actual Spring beans including some JPA repos
class LogicSpec extends Specification {
  @SpringBean
  RestService restService = Stub()
  @Autowired
  ServiceUnderTest sut
  @Autowired
  SomeJPARepo repository;

  def 'should do some business logic'() {
    given:
      Message m = new Stub() {
        getStatus() >> "stubbed status"
      }
      restService.getMessage(_ as String) >> {
        m
      }
    when:
      sut.businessMethod()
    then:
      // just checking for side effects that `businessMethod` causes, no mocks being matched against
      assert repository.findAll().every { it.processed == true }  
    }
  }
}

在内部, ServiceUnderTest.businessMethod()使用Message对象,如下所示:

restService.getMessage(sid).getStatus() // should be "stubbed status"; always evaluates to null

但是,无论我是否为它定义了一个行为, Message stub的每个方法总是返回 null。 Message对象必须从其 getter 中返回特定值才能使测试正常工作。 我宁愿不必将每个Message存根声明为自己的@SpringBean 我最终需要扩展测试以使用几个不同的Message存根对象。 我不需要模拟或间谍,因为调用RestService的方法的次数并不重要,我只需要它发出适当的存根供ServiceUnderTest咀嚼。 如果这个问题不寻常或者我错过了一些明显的东西,我们深表歉意; 我对 Spock 的生命周期概念有点忘记,而且随着 Spring 扩展的添加,水变得特别混乱。

写完这篇文章后我很快就找到了答案,但只是为了后代; 第三方Message类被声明为final ,因此不能被子类化; Spock 正在为它们创建存根,但默默地没有添加被覆盖的模拟方法。 我最终使用PowerMockito来消除这个限制; 然而,这干扰了收集测试覆盖率指标,所以我改用了一个可以模拟的包装类,并在我的代码中到处使用它,原来的 Message 类是:

public class MessageWrapper {
  public MessageWrapper(Message from) {...}
}

这有点让人头疼,但这是必要的,因为在这种情况下需要测试覆盖率。 似乎还有一个很有前途的特定于 Spock 的模拟实用程序可以模拟最终类,但我没有测试过它,也不知道它是否会像 PowerMockito 那样干扰收集覆盖率指标。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM