我正在尝试在动态支架控制器的集成测试中模拟服务。我收到一个错误,指示无法从测试中访问该服务的控制器属性。
似乎动态支架控制器根本无法使用单元测试进行测试,所以我正在使用集成测试。我想模拟服务来测试我的应用程序中的错误处理。这是Grails 2.2.0中的错误还是我做错了?
grails test-app
的结果是:
groovy.lang.MissingPropertyException: No such property: myService for class: MyController
示例:
我修改了src/templates/scaffolding/Controller.groovy
:
class ${className}Controller {
MyService myService
def action() {
render myService.serviceMethod()
}
}
动态搭建MyController.groovy
:
class MyController {
static scaffold = MyDomainClass
}
整合测试MyControllerTests.groovy
:
class MyControllerTests extends GroovyTestCase {
def myController
@Before
void setUp() {
myController = new MyController()
}
void testMock() {
myController.myService = [ serviceMethod : { return "foo" } ] as MyService
controller.action()
}
}
答案 0 :(得分:2)
尝试使用setter方法:
void testMock() {
myController.setMyService([ serviceMethod : { return "foo" } ])
controller.action()
}
如果执行:println c.metaClass.methods*.name
,您将看到有getSetMyService()和getGetMyService()等方法。我不确定,但Grails可能不会添加字段,而是使用get get / set方法获取字段。
答案 1 :(得分:0)
集成测试应如下所示实现。如果我们在测试中模拟服务,我们必须自己重置它。由于控制器是在setUp()
中创建的,所以Grails不会为我们这样做,因为它是神秘的。
droggo上面的回答揭示了在SUT中注入模拟的正确方法。我还将添加一个使用Groovy模拟的示例。但它有点冗长。
class MyControllerTests extends GroovyTestCase {
def myController
def myService
@Before
void setUp() {
myController = new MyController()
}
@After
void tearDown() {
myController.setMyService(myService)
}
void testMapMock() {
myController.setMyService([ serviceMethod : { return "foo" } ] as MyService)
controller.action()
}
void testGroovyMock() {
def myServiceMockContext = new StubFor(MyService)
myServiceMockContext.demand.serviceMethod() { -> return "bar" }
def myService = myServiceMockContext.proxyInstance()
controller.setMyService(myService)
controller.action()
}
}