![](/img/trans.png)
[英]Spring Boot integration test with Spock: stubbed method returns 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.