Unit testing 在域类中测试服务
我现在正试图为我的一个域类编写一个单元测试。我作弊了,我知道代码是用代码工作的,但是。。。我想确保我有一些自动测试 我得到以下错误:Unit testing 在域类中测试服务,unit-testing,grails,grails-2.0,Unit Testing,Grails,Grails 2.0,我现在正试图为我的一个域类编写一个单元测试。我作弊了,我知道代码是用代码工作的,但是。。。我想确保我有一些自动测试 我得到以下错误: Test a sponsor(some.vendor.Vendor2Spec) | java.lang.NullPointerException: Cannot invoke method getLevel() on null object at some.vendor.Vendor.getSponsorLevel(Vendor.groovy:1
Test a sponsor(some.vendor.Vendor2Spec)
|
java.lang.NullPointerException: Cannot invoke method getLevel() on null object
at some.vendor.Vendor.getSponsorLevel(Vendor.groovy:111)
at some.vendor.Vendor2Spec.Test a sponsor(Vendor2Spec.groovy:29)
|Completed 1 unit test, 1 failed in 0m 3s
.................Tests FAILED
在下面的代码中,我指出了我的行号,这些行号被称为错误
我的供应商
看起来像:
class Vendor {
def sponsorService
SponsorLevel getSponsorLevel(){
return sponsorService.getLevel(this) // Line 111
}
}
class SponsorService {
static transactional = false
def getLevel(Vendor vendor){
if(!vendor){
return null
}
BigDecimal sponsoringAmount = BigDecimal.ZERO
sponsoringAmount = sponsoringAmount.add(vendor.cashDonation ?: BigDecimal.ZERO)
sponsoringAmount = sponsoringAmount.add(vendor.itemValue ?: BigDecimal.ZERO)
return SponsorLevel.getSponsoringLevel(sponsoringAmount)
}
}
我的测试设置如下:
@TestFor(Vendor)
@TestMixin(GrailsUnitTestMixin)
class Vendor2Spec extends Specification{
@Shared
def sponsorService = new SponsorService()
def setup() {
}
def cleanup() {
}
void "Test a sponsor"(){
when: 'A Sponsor donates $5'
def vendor = new Vendor(cashDonation: 5, sponsorService: sponsorService)
then: 'Amount Owed should be $5'
vendor.getAmountDue().equals(new BigDecimal("5"))
vendor.getSponsorLevel() == SponsorLevel.DIAMOND // Line 29
when:"A Sponsor donates an item of value"
vendor = vendor = new Vendor(itemValue: 5)
then: 'Amount Due is $0'
vendor.getAmountDue().equals(new BigDecimal("0"))
vendor.sponsorLevel == SponsorLevel.DIAMOND
}
}
当我刚开始的时候,我并没有更新我的赞助商服务
,它一直在抱怨为空,所以。。。我试着嘲笑(可能做错了),但是。。。我需要测试服务的对象使用情况,以便。。。我想我不需要嘲笑
该服务看起来像:
class Vendor {
def sponsorService
SponsorLevel getSponsorLevel(){
return sponsorService.getLevel(this) // Line 111
}
}
class SponsorService {
static transactional = false
def getLevel(Vendor vendor){
if(!vendor){
return null
}
BigDecimal sponsoringAmount = BigDecimal.ZERO
sponsoringAmount = sponsoringAmount.add(vendor.cashDonation ?: BigDecimal.ZERO)
sponsoringAmount = sponsoringAmount.add(vendor.itemValue ?: BigDecimal.ZERO)
return SponsorLevel.getSponsoringLevel(sponsoringAmount)
}
}
以及枚举:
enum SponsorLevel {
PLATINUM("Platinum"),
GOLD("Gold"),
SILVER("Silver"),
BRONZE("Bronze"),
DIAMOND("Diamond")
final String label
private SponsorLevel(String label){
this.label = label
}
public static SponsorLevel getSponsoringLevel(BigDecimal sponsoringAmount){
if(!sponsoringAmount){
return null
}
if(sponsoringAmount.compareTo(new BigDecimal("3000")) >= 0){
return PLATINUM
}
if(sponsoringAmount.compareTo(new BigDecimal("2000")) >= 0){
return GOLD
}
if(sponsoringAmount.compareTo(new BigDecimal("1000")) >= 0){
return SILVER
}
if(sponsoringAmount.compareTo(new BigDecimal("500")) >= 0){
return BRONZE
}
if(sponsoringAmount.compareTo(new BigDecimal("1")) >= 0){
return DIAMOND
}
return null
}
}
一般来说,当从其他类调用服务类进行单元测试时,应该模拟服务类,否则,您可能需要编写集成测试 就个人而言,如果这就是您的服务所做的一切,我会将其作为域本身的一种方法:
class Vendor {
def sponsorService
SponsorLevel getSponsorLevel(){
BigDecimal sponsoringAmount = BigDecimal.ZERO
sponsoringAmount = sponsoringAmount.add(this.cashDonation ?: BigDecimal.ZERO)
sponsoringAmount = sponsoringAmount.add(this.itemValue ?: BigDecimal.ZERO)
return SponsorLevel.getSponsoringLevel(sponsoringAmount)
}
}
您的服务不是事务性的,您的
getLevel()
对数据库没有任何作用,并且该方法特定于您的供应商域。所以对我来说,将其作为供应商的域方法更有意义。它简化了您的代码和测试。这绝对是可能的!我会回去看看,看看其他东西是如何相互作用的。我还有其他一些事情没有包括在这里。最初,从供应商
到赞助商服务
的呼叫是为了便于使用,但感谢您的输入。