Grails Quartz Job Integration test - Not autowired Job

grails, integration-testing, quartz-scheduler

Solution

Quartz Jobs are not autowired like services are under the test environment. The documentation for the Quartz job also explicitly states that by default it will not execute on schedule under the test environment (you could change that if you want to but I wouldn't). I would just instantiate `myJob = new MyJob()` in your `setUp` and call the `execute()` method to test it. If you're trying to test the triggers you may want to find a way to look at what is inside the `triggers {}` maybe inspecting the metaClass?

EDIT IN RESPONSE TO COMMENT:

I've never gotten the services out of the application context so that might work. The way I would probably test it is as follows:

Assuming your class looks something like this:

class MyJob {
    def myServiceA
    def myServiceB

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

    }        
}

What you're really wanting to test here is the `myJobLogicToDetermineWhatToDo`. I would assume that you have (or can easily write) integration and/or unit tests against your services myServiceA and myServiceB to ensure that they are working correctly. I would then write unit tests to test the logic/wiring of your Job to the appropriate service.

@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
}

Then repeat this process for all of the routes you have through your Job. This way you can isolate your tests down to the smallest part possible and test the logic of the object that you're invoking not the services it is using. I would assume you're using a service because the logic in there is being used by another part of the system. If you're testing the service through this job and for some reason the job goes away then you have to re-write your tests to invoke the service directly. The way that I've proposed you have tests testing the service directly and tests that mock out those service calls. If the job goes away you would simply delete the tests associated with it and you won't loose any test coverage. Kinda long winded but that's how I would approach testing it.

Problem

I'm writing the Integration test for a Quartz Job in a grails application. I've the Job in grails-app/jobs folder, and if I start the application it works. The problem is that I want to get it in an integration test, but the autowire won't work. The test is like: ``` class MyJobTest{ MyJob myJob def setUp(){ assert myJob != null } def testExecute(){ //test logic } } ``` but it fails because myJob is null...some help?

Original source