【发布时间】:2014-04-28 22:56:08
【问题描述】:
我正在使用 Grails 2.3.7。我有一个简单的 Person 域对象:
class Person {
String name
static constraints = {}
}
和控制器:
@Transactional(readOnly = true)
class PersonController {
def index() {
render view:'index', model:[personList:Person.list()]
}
def show(Long id) {
def person = Person.get(id)
render view:'show', model:[person:person]
}
...
}
我正在尝试为控制器编写一个单元测试来执行show 方法,但我不确定我需要如何配置测试以确保静态调用Person.get(id) 返回一个值。
这是我的(失败的)尝试:
import grails.test.mixin.*
import spock.lang.*
@TestFor(PersonController)
@Mock(Person)
class PersonControllerSpec extends Specification {
void "Test show action loads Person by id and includes that person in the model rendered"() {
setup:
def personMockControl = mockFor(Person)
personMockControl.demand.static.get() { int id -> new Person(name:"John") }
when:"A valid person id passed to the show action"
controller.show(123)
then:"A model is populated containing the person domain instance loaded by that unique id"
model.person != null
model.person.name == "John"
}
}
此测试失败,因为条件 model.person != null 失败。如何重写此测试以使其通过?
编辑
在这种情况下,我可以通过重做测试来避开静态方法调用:
void "Test show action loads Person by id and includes that person in the model rendered"() {
setup:
def p = new Person(name:"John").save()
when:"A valid person id passed to the show action"
controller.show(p.id)
then:"A model is populated containing the person domain instance loaded by that unique id"
model.person != null
model.person.id == p.id
model.person.name == "John"
}
但是,我真的很想了解如何正确模拟 Person 的静态 get 方法。
编辑 2
这是另一种情况来证明我认为需要模拟 get 方法。鉴于此过滤器代码:
def fitlers = {
buyFilter(controller:"paypal", action:"buy") {
after = {
new VendorPayment(payment:request.payment, vendor: Vendor.get(params.buyerId)).save()
}
}
}
我正在尝试使用以下测试测试此过滤器是否按预期工作:
void "test the buyFilter to ensure it creates a VendorPayment when the PayPal plugin controller is called" () {
setup:
// how do I mock the Vendor.get(params.buyerId)
// to return a vendor in order to save a new VendorPayment
when:
withFilters(action:"buy") {
controller.buy()
}
then:
VendorPayment.count() == 1
}
【问题讨论】:
-
为什么需要模拟
get方法?您已经在测试中模拟了Person并创建了一个模拟的 Person 实例。让 GORM 在show中提取所需的 Person 实例?有帮助吗? -
我试图编造一个需要模拟
get方法的简单示例,也许这个示例过于简单。我将编辑问题以添加更复杂的情况。
标签: unit-testing grails mocking