Search code examples
grailsgrails-2.0

Grails unit tests: Accessing defined beans via grailsApplication


I have some (non-Grails-artifact) classes that access the service layer beans via passing around the grailsApplication object. However I'm having trouble unit testing the classes implemented in this way. Why doesn't the bean get registered in the main context?

@TestMixin(GrailsUnitTestMixin)
class ExampleTests {
  void setUp() {}

  void tearDown() {}

  void testSomething() {
    defineBeans {
      myService(MyService)
    }

    assert grailsApplication.mainContext.getBean("myService") != null
  }
}

The above code fails with:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'myService' is defined

What I'm trying to do is access services from plain old Java classes via the grailsApplication. This works, but not in unit test environment. Should I do it differently?

class POJO {
  MyService myService;

  public POJO(GrailsApplication grailsApplication) {
    myService = (MyService) grailsApplication.getMainContext().getBean("myService");
  }
}

Solution

  • The answer is that in the GrailsUnitTestMixin the applicationContext that holds your beans is set as the parentContext in the grailsApplication

    beans.registerBeans(applicationContext)
    
    static void initGrailsApplication() {
    ...
    //the setApplicationContext in DefaultGrailsApplication set's the parentContext
    grailsApplication.applicationContext = applicationContext
    }
    

    So you can get your beans with:

    defineBeans {
      myService(MyService)
    }
    
    assert applicationContext.getBean("myService")
    assert grailsApplication.parentContext.getBean("myService")
    

    EDIT

    Today I faced the same problem, and my solution is:

    @Before
    void setup() {
      Holders.grailsApplication.mainContext.registerMockBean("myService", new MyService())
    }