在控制器测试期间无法保存
Failing to save during Test on Controller
我已经为此苦苦挣扎了一段时间,这似乎是一个常见问题,没有适合我的解决方案。
我想做的是测试调用 save() 的控制器,并且在 save() 内部,该方法调用服务以使用给定的命令对象保存员工。
代码如下所示:
def save(EmployeeInputCommand employeeCommand, AddressCommand addressCommand) {
if (addressCommand.address.validate()) {
println "Validated address input"
employeeManagerService.save(employeeCommand, addressCommand)
println "Employee should be saved"
println "------------------------->"
println "${employeeGetterService.each {errors}}"
flash.message = "Employee has been successfully created!"
redirect(action: "index")
} else {
println "Addrescommand didnt validate: ${addressCommand.errors}"
flash.message = "Please input valid data!!!"
redirect(action: "create", model: [employee: employeeCommand, address: addressCommand])
}
}
该服务包含以下内容:
def save(EmployeeInputCommand employeeCommand, AddressCommand addressCommand) {
def employee = new Employee(employeeCommand.properties)
employee.address = addressCommand.address
for (id in employeeCommand.s) {
employee.addToSkills(Skill.get(id))
}
if (employee.validate()) {
employee.address.save()
employee.save()
}
else {
return false
}
}
当我尝试将员工实际保存在我的应用程序中时,我知道这有效,但在单元测试过程中没有任何反应。
我的测试:
def "Create an Employee with good params"() {
given: "A valid employee command object"
def employeeCommand = new EmployeeInputCommand(
name: "John",
surname: "Smith",
birthdate: Date.parse("yyyy-MM-dd", "1992-06-08"),
salary: 21000,
s: [1, 3, 5]
)
and: "Also a valid address command object"
def addressCommand = new AddressCommand(
street: "Green Alley",
houseid: "42",
city: "Odense",
county: "Fyn",
postCode: "5000 C"
)
expect:
addressCommand.validate()
!Employee.findByNameAndSurname("John", "Smith")
when: "Saving employee"
request.method = "POST"
controller.save(employeeCommand, addressCommand)
Employee employee = Employee.findByNameAndSurname("John", "Smith")
println Employee.list()
then: "The employee is created, and browser redirected"
Employee.count == 4
employee
employee.skills.size() == 3
employee.address.postCode == "5000 C"
}
调用 controller.save() 时测试失败并出现空错误。我花了太多时间试图解决这个问题,但都是徒劳
这是输出截图
我认为问题在于单元测试中的服务。在单元测试中,您需要 defineBeans
闭包才能使用 spring beans-
void "test the filter"() {
setup:
defineBeans {
employeeManagerService(EmployeeManagerService) { bean ->
bean.autowire = true
}
}
when:
...
then:
...
}
参考号Inject Services in Grails Unit Test
我不认为测试控制器应该涵盖服务逻辑。如果我要为控制器编写单元测试,我会模拟该服务,并在其自己的 unit/integration 测试中单独测试该服务。
例如:
/*
* in controller spec
*/
def setup() {
def serviceMock = new MockFor(EmployeeManagerService)
serviceMock.ignore('save') { ec, ac ->
Employee.buildWithoutSave().save(validate: false)
}
serviceMock.use {
controller.employeeManagerService = new EmployeeManagerService()
}
}
def 'testFoo'() {
when:
// ...
controller.employeeManagerService.save()
// ...
then:
// ...
}
请注意,代码使用的是优秀的Build Test Data plugin。
您需要将测试作为集成测试执行,而不是单元测试。当您测试与数据库相关的逻辑(CRUD 操作)时需要集成测试,而不仅仅是模拟单元测试所做的 CRUD 操作。
我已经为此苦苦挣扎了一段时间,这似乎是一个常见问题,没有适合我的解决方案。
我想做的是测试调用 save() 的控制器,并且在 save() 内部,该方法调用服务以使用给定的命令对象保存员工。
代码如下所示:
def save(EmployeeInputCommand employeeCommand, AddressCommand addressCommand) {
if (addressCommand.address.validate()) {
println "Validated address input"
employeeManagerService.save(employeeCommand, addressCommand)
println "Employee should be saved"
println "------------------------->"
println "${employeeGetterService.each {errors}}"
flash.message = "Employee has been successfully created!"
redirect(action: "index")
} else {
println "Addrescommand didnt validate: ${addressCommand.errors}"
flash.message = "Please input valid data!!!"
redirect(action: "create", model: [employee: employeeCommand, address: addressCommand])
}
}
该服务包含以下内容:
def save(EmployeeInputCommand employeeCommand, AddressCommand addressCommand) {
def employee = new Employee(employeeCommand.properties)
employee.address = addressCommand.address
for (id in employeeCommand.s) {
employee.addToSkills(Skill.get(id))
}
if (employee.validate()) {
employee.address.save()
employee.save()
}
else {
return false
}
}
当我尝试将员工实际保存在我的应用程序中时,我知道这有效,但在单元测试过程中没有任何反应。
我的测试:
def "Create an Employee with good params"() {
given: "A valid employee command object"
def employeeCommand = new EmployeeInputCommand(
name: "John",
surname: "Smith",
birthdate: Date.parse("yyyy-MM-dd", "1992-06-08"),
salary: 21000,
s: [1, 3, 5]
)
and: "Also a valid address command object"
def addressCommand = new AddressCommand(
street: "Green Alley",
houseid: "42",
city: "Odense",
county: "Fyn",
postCode: "5000 C"
)
expect:
addressCommand.validate()
!Employee.findByNameAndSurname("John", "Smith")
when: "Saving employee"
request.method = "POST"
controller.save(employeeCommand, addressCommand)
Employee employee = Employee.findByNameAndSurname("John", "Smith")
println Employee.list()
then: "The employee is created, and browser redirected"
Employee.count == 4
employee
employee.skills.size() == 3
employee.address.postCode == "5000 C"
}
调用 controller.save() 时测试失败并出现空错误。我花了太多时间试图解决这个问题,但都是徒劳
这是输出截图
我认为问题在于单元测试中的服务。在单元测试中,您需要 defineBeans
闭包才能使用 spring beans-
void "test the filter"() {
setup:
defineBeans {
employeeManagerService(EmployeeManagerService) { bean ->
bean.autowire = true
}
}
when:
...
then:
...
}
参考号Inject Services in Grails Unit Test
我不认为测试控制器应该涵盖服务逻辑。如果我要为控制器编写单元测试,我会模拟该服务,并在其自己的 unit/integration 测试中单独测试该服务。 例如:
/*
* in controller spec
*/
def setup() {
def serviceMock = new MockFor(EmployeeManagerService)
serviceMock.ignore('save') { ec, ac ->
Employee.buildWithoutSave().save(validate: false)
}
serviceMock.use {
controller.employeeManagerService = new EmployeeManagerService()
}
}
def 'testFoo'() {
when:
// ...
controller.employeeManagerService.save()
// ...
then:
// ...
}
请注意,代码使用的是优秀的Build Test Data plugin。
您需要将测试作为集成测试执行,而不是单元测试。当您测试与数据库相关的逻辑(CRUD 操作)时需要集成测试,而不仅仅是模拟单元测试所做的 CRUD 操作。