2014-02-14 135 views
2

我想运行服务的单元测试。我想测试的方法包括一些log.debug()声明。虽然log属性在运行时注入的,它似乎并没有在测试中被注入,所以它抛出groovy.lang.MissingPropertyException: No such property: log for class:Grails单元测试服务MissingProperty'log'

这是我的单元测试类:

@TestFor(ServiceUnderTest) 
@Mock([ServiceUnderTest]) 
class ServiceUnderTestTests { 

    def test() { 
     def mock = [ mockedProp: [...] ] as ServiceUnderTest 
     def info = mock.doOperation() 
     assert .... 
    } 
} 

我也尝试添加MockUtils.mockLogging(ServiceUnderTest)但没有成功。

如何在单元测试中正确注入我的服务类中的日志属性?

回答

4

您不必拥有用@Mock([ServiceUnderTest])注释的测试类。 @TestFor(ServiceUnderTest)检测到它的服务类,并自动执行所有的模拟。它还将service属性添加到可以在所有测试方法中访问的测试类,并相应地嘲笑log属性。

我认为这个问题为什么没有嘲讽,也没有明确的日志,MockUtils.mockLogging(ServiceUnderTest)嘲讽确实工作你的情况是你正在使用的测试方法的代码as威逼:

def mock = [ mockedProp: [...] ] as ServiceUnderTest 

Groovy的内部使用java.lang.reflect.Proxy创建一个代理从ServiceUnderTest后裔类。代理类不会看到对ServiceUnderTest元类的更改,例如添加的log属性。

我会通过使用每个对象元类使用来解决此问题。您可以通过更改service对象的metaClass来模拟属性获取器(或设置器)。请注意,元类更改由Grails在执行测试方法之间回退:

service.metaClass.mockedProp = {-> ... } 
+0

谢谢你的工作。 Groovy非常强大,在特定问题上使用正确的方式很难...... – matcauthon

+0

是的,幕后发生了很多事情。有时候,就像在这个例子中,你需要知道一些这些东西:-) –