Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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");
  }
}
like image 787
djh Avatar asked Dec 18 '25 07:12

djh


2 Answers

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())
}

In my case (grails 2.4.4) the accepted solution didn't work but pointed me in the right direction, this line worked instead as the bean factory in the mainContext within my unit test was an OptimizedAutowireCapableBeanFactory

Holders.grailsApplication.mainContext.beanFactory.registerSingleton('myBean', new MyBeanClass())
like image 40
Ed OConnor-Giles Avatar answered Dec 20 '25 00:12

Ed OConnor-Giles



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!