unit-testing - 返回的模拟对象具有所有导致测试失败的空字段
问题描述
我有一个使用名为 ReportingService 的服务的简单类。它被注入到类中,我正在验证它是否被调用并带有预期的参数。模拟通过确保 reportType 和其他值符合预期,返回我想在测试中断言的 ReportSummary 对象。不幸的是,ReportSummary 字段都是空的,我做错了什么?
class ReportSummary {
String reportType
Date createdTime
String reportedById
}
class ReportingService {
ReportSummary updateReport(Report reportData) {
...
}
}
该服务被注入到一个类 PricingService 中,如下所示:
class PricingService {
@Autowired
ReportingService reportingService
ReportingSummary updatePricingDetails( ReportData data) {
reportingService.updateReport(data)
}
}
该类在这样的服务中使用
class PricingServiceSpec extends Specification {
ReportingService reportingService = Mock()
PricingService pricingService = new PricingService( reportingService)
ReportData data = new ReportData(........)
def "Should return summary report data" (){
given:
Date today = new Date (System.currentMillis())
ReportSummary summary = new ReportSummary(reportType: 'Pricing',createdTime:
today, reportedById: 'GXT111111345')
when:
ReportSummary response = pricingService.updatePricingDetails(data)
then:
1 * reportingService.updateReport( data : {
assert it.pricingDescription == 'Pricing for Produce'
}) >> summary
response.reportType == 'Pricing' // The reportType is null why?
response.reportedById == 'GXT111111345' // The reportById is null, why? The
0 * _
)
}
}
解决方案
这是一些示例代码,它至少可以编译并模拟您的情况,即使它返回一些虚拟数据(但至少与您要测试的存根结果不同):
package de.scrum_master.stackoverflow.q67912725
class ReportData {
String pricingDescription;
}
package de.scrum_master.stackoverflow.q67912725
class ReportSummary {
String reportType
Date createdTime
String reportedById
}
package de.scrum_master.stackoverflow.q67912725
class ReportingService {
ReportSummary updateReport(ReportData reportData) {
return new ReportSummary(
reportType: "real report",
createdTime: new Date(),
reportedById: "me"
)
}
}
package de.scrum_master.stackoverflow.q67912725
import org.springframework.beans.factory.annotation.Autowired
class PricingService {
@Autowired
ReportingService reportingService
ReportSummary updatePricingDetails(ReportData data) {
reportingService.updateReport(data)
}
}
这是一个通过测试。您的基本问题是您试图在方法约束中使用方法参数名称,即在您的原始代码中data :
断言闭包之前的部分。方法参数按类型和位置匹配,而不是按参数名称。忽略它,你很好。
顺便说一句,您也不应该assert
在方法参数约束中使用,而是一个简单的布尔表达式。一个失败的断言会使测试失败,这不是你想要的。您只是想匹配一个参数值。
修复测试对我来说并不难。我花了 10 倍的时间才真正编译这个烂摊子并做一些合乎逻辑的事情,甚至开始分析测试。
package de.scrum_master.stackoverflow.q67912725
import spock.lang.Specification
class PricingServiceTest extends Specification {
def reportingService = Mock(ReportingService)
def pricingService = new PricingService(reportingService: reportingService)
def reportData = new ReportData(pricingDescription: 'Pricing for Produce')
def "Should return summary report data"() {
given:
ReportSummary stubbedSummary = new ReportSummary(
reportType: 'Pricing',
createdTime: new Date(),
reportedById: 'GXT111111345'
)
when:
ReportSummary reportSummary = pricingService.updatePricingDetails(reportData)
then:
1 * reportingService.updateReport(
{ it.pricingDescription == 'Pricing for Produce' }
) >> stubbedSummary
reportSummary.reportType == stubbedSummary.reportType
reportSummary.reportedById == stubbedSummary.reportedById
0 * _
}
}
推荐阅读
- java - 在java中搜索一个数组并打印输出
- python - 从一个数据帧中查找匹配值并发送到另一个数据帧
- java - 忽略/不使用方法结果时的编译器错误
- javascript - 如何在一个循环中添加 onClick 事件并在另一个循环中的相应元素上切换类?
- spring-boot - Kubernetes 上的 RabbitMQ 队列中未确认的消息
- c# - 使用接口与实现接口的通用类型之间的区别
- android - 蓝牙 BLE 无法连接
- javascript - 在 React 的粘贴/拖放事件中接收图像文件
- docker - Kubernetes - minikube 服务连接超时
- java - java - 如何使用正则表达式java删除删除以仅从字符串中获取数值?