2012-05-03 110 views
3

我正在为grails应用程序中的Quartz作业编写集成测试。 我在grails-app/jobs文件夹中找到了工作,如果我启动该应用程序,它就可以工作。问题是我想在集成测试中获得它,但自动装配不起作用。测试是这样的:Grails Quartz作业集成测试 - 非自动作业作业

class MyJobTest{ 
    MyJob myJob 
    def setUp(){ 
     assert myJob != null 
    } 

    def testExecute(){ 
     //test logic 
    } 

} 

但它失败,因为myJob为空...有些帮助吗?

回答

4

石英作业不是自动布线的,就像服务处于测试环境下一样。 Quartz作业的文档还明确指出,默认情况下,它不会在测试环境下按计划执行(如果需要,可以更改,但我不会)。我只是在您的setUp中实例化myJob = new MyJob()并调用​​方法来测试它。如果你想测试触发器,你可能想要找到一种方法来看看triggers {}里面的内容,也许检查metaClass?

编辑回应评论:

我从来没有得到的服务进行应用程序上下文的,这样可能会奏效。我可能会测试它的方法如下:

假设你的类看起来是这样的:

class MyJob { 
    def myServiceA 
    def myServiceB 

    def execute() { 
     if(myJobLogicToDetermineWhatToDo) { 
      myServiceA.doStuff(parameter) 
     } else { 
      myServiceB.doStuff(parameter) 
     } 

    }   
} 

你真正想在这里测试的是myJobLogicToDetermineWhatToDo。我假设你已经(或者可以很容易地编写)针对服务myServiceA和myServiceB的集成和/或单元测试,以确保它们正常工作。然后我会编写单元测试来测试你的Job的逻辑/接线到相应的服务。

@Test 
void routeOne() { 
    def job = new MyJob() 
    def myServiceA = new Object() 
    def expectedParameter = "Name" 
    def wasCalled = false 
    myServiceA.metaClass.doStuff = {someParameter -> 
     assert expectedParameter == someParameter 
     wasCalled = true 
    } 
    job.myServiceA = myServiceA 
    //Setup data to cause myServiceA to be invoked 

    job.execute() 

    assert wasCalled 
} 

然后对您通过作业完成的所有路线重复此过程。通过这种方式,您可以将测试划分为尽可能最小的部分,并测试您调用的对象的逻辑,而不是它所使用的服务的逻辑。我会假设你正在使用一个服务,因为那里的逻辑被系统的另一部分使用。如果您通过这项工作测试服务,出于某种原因,工作将消失,那么您必须重新编写测试以直接调用服务。我建议你的方式是直接测试服务并测试那些服务调用。如果作业消失,您只需删除与其关联的测试,并且不会丢失任何测试覆盖范围。有点长时间啰嗦,但这就是我将如何进行测试。

+0

非常感谢!问题是Quartz在执行时有一些逻辑,它执行某些服务的方法...所以在测试中,我必须实例化Job类并自己注入应用程序上下文中的服务,对吧? – rascio

+0

我发现了另一个解决方案:在grails quartz插件中有一个命令: grails install-quartz-config。这会创建QuartzConfig.groovy文件,其中能够使装石英时钟为测试: 环境{ 测试{ 石英{ 的自动启动=假 } } } 更多细节:[Grails的文档](HTTP:/ /grails-plugins.github.io/grails-quartz/guide/configuration.html) – Nazar