Unit testing 具有模拟服务的单元测试筛选器
我正在使用Grails2.3.8,并试图为使用服务的过滤器创建一个单元测试 过滤器:Unit testing 具有模拟服务的单元测试筛选器,unit-testing,grails,service,filter,Unit Testing,Grails,Service,Filter,我正在使用Grails2.3.8,并试图为使用服务的过滤器创建一个单元测试 过滤器: class LicenseFilters { def licenseService def filters = { all(controller:'*', action:'*') { before = { if(!licenseService.checkLicense()){ re
class LicenseFilters {
def licenseService
def filters = {
all(controller:'*', action:'*') {
before = {
if(!licenseService.checkLicense()){
redirect(controller:"licenseExpired")
return false
}
}
}
}
}
规范,第一次尝试:
@TestFor(ExecutionTraceController)
@Mock(LicenseFilters)
class LicenseFiltersSpec extends Specification{
void "Test filter redirects when license is wrong"() {
given:
LicenseFilters bean=applicationContext.getBean("com.nortia.sgmentia.license.LicenseFilters")
bean.licenseService=this.buildLicenseServiceStub(false)
when:
withFilters(action:"list") {
controller.list()
}
then:
response.redirectedUrl == '/licenseExpired'
}
private LicenseService buildLicenseServiceStub(boolean ok){
LicenseService result=Stub(LicenseService)
result.checkLicense() >> ok
return result
}
}
但是(通过调试)结果是,我从上下文获取的bean与接收请求的bean不同,因此我仍然得到一个NPE
在第二次尝试中,我尝试使用定义bean:
void "Test filter redirects when license is wrong"() {
given:
defineBeans {
licenseService(MethodInvokingFactoryBean){
targetObject = this
targetMethod= "buildLicenseServiceStub"
arguments=[false]
}
}
when:
withFilters(action:"list") {
controller.list()
}
then:
response.redirectedUrl == '/licenseExpired'
}
但是模拟的bean既不是实例化的,也不是插入的
我是否应该尝试手动将服务输入过滤器??
有这个问题,但它已经解决了。我终于找到了一个解决方法,使第二种方法(使用defineBeans)能够正常工作 该服务没有自动连接到筛选器中,因此我最终使用伪单例手动执行了该操作:
class LicenseFilters {
def licenseService
def filters = {
all(controller:'*', action:'*') {
before = {
if(!this.licenseService){
this.licenseService=applicationContext.getBean("licenseService")
}
if(!this.licenseService.checkLicense()){
redirect(controller:"licenseExpired")
return false
}
}
}
}
}
很难看,但至少是个解决办法。
希望它能帮助其他人。我遇到了类似的情况,并且能够通过将该服务添加到@Mock注释中来修复它,即
@Mock([LicenseFilters,LicenseService])
在您的情况下,规范将如下所示:
@TestFor(ExecutionTraceController)
@Mock([LicenseFilters, LicenseService])
class LicenseFiltersSpec extends Specification {
void "Test filter redirects when license is wrong"() {
given:
defineBeans {
licenseService(MethodInvokingFactoryBean) {
targetObject = this
targetMethod = "buildLicenseServiceStub"
arguments = [false]
}
}
when:
withFilters(action: "list") {
controller.list()
}
then:
response.redirectedUrl == '/licenseExpired'
}
private LicenseService buildLicenseServiceStub(boolean ok) {
LicenseService result = Stub(LicenseService)
result.checkLicense() >> ok
return result
}
}
注意:默认情况下,以这种方式模拟服务将向过滤器中注入实际LicenseService的实例。因此,如果删除上面的defineBeans块,将调用LicenseService.checkLicense()的实际实现