How do you test service or controller methods in grails 2.3
Asked Answered
L

2

6

I'm just starting out with grails 2.3 and I have problems getting the unit tests to run. What I've done so far is I've run

grails create-app new-app
grails create-service NewService
grails test-app

This produces

| Running 1 unit test...
| Completed 0 unit test, 0 failed in 0m 2s
| Tests PASSED - view reports in C:\Git\aspera_web\target\test-reports

So far so good but if I edit the method

void "test something"() {
}

in the NewServiceSpec class to

void "test something"() {
    assert false
}

and run again I again get

| Running 1 unit test...
| Completed 0 unit test, 0 failed in 0m 2s
| Tests PASSED - view reports in C:\Git\aspera_web\target\test-reports

I then looked into the spock documentation and tried to edit my test again. This time to

void "test something"() {
    expect: 1 == 2
}

which produces

| Running 1 unit test...
| Running 1 unit test... 1 of 1
| Failure:  test something(aspera_web.NewServiceSpec)
|  Condition not satisfied:
false
        at aspera_web.NewServiceSpec.test something(NewServiceSpec.groovy:19)
| Completed 1 unit test, 1 failed in 0m 2s
| Tests FAILED  - view reports in C:\Git\aspera_web\target\test-reports

which looks promising so then the next step is to test methods in my NewService class so I again change my test to

def service = new NewSevice()
void "test something"() {
    expect: service.serviceMethod()
}

and when I run it I get

| Running 1 unit test...
| Running 1 unit test... 1 of 1
| Failure:  test something(aspera_web.NewServiceSpec)
|  java.lang.NullPointerException
        at aspera_web.NewServiceSpec.test something(NewServiceSpec.groovy:21)
| Completed 1 unit test, 1 failed in 0m 2s
| Tests FAILED  - view reports in C:\Git\aspera_web\target\test-reports

just for good measure I also added a test directly from the Spock exmaples

def stack = new Stack()
def "size"() {
    expect: stack.size() == 0
}

Which works like a charm...

So at last my question:

  • How do I test my own service/controller methods (I get the exact same result if I replace create-service with create-controller)

EDIT

Apparently this is a bug in Grails 2.3.0 see my answer below.

Lunate answered 25/9, 2013 at 7:59 Comment(4)
You'll have to instantiate the service object in order to use it in the test. The expect rhs should evaluate to a Boolean.Lisa
My english is not what it should be but dont I instantiate my service with def service = new NewService() or what do you mean?Lunate
Indirectly yes. It's likely that the framework and/or the annotation creates an instance of the object that you can then reference so I doubt that you need to manually instantiate the object but the Service does not exist from reading the stacktrace. Who advised that this should be logged as a bug?Lisa
Like I mention in the bug report when I remove the @Transaction annotation then the service gets instantiated by the framework and everything works just fine thats why I reported it.Lunate
L
5

The solution was to go into the generated service class and remove the @Transaction parameter. Then for some reason the service variable in the test gets instantiated.

I've filed a JIRA report about it.

Workaround

Just remove the annotation and add the line

static transactional = true

to the service instead to get the same behaviour.

Lunate answered 25/9, 2013 at 14:16 Comment(0)
B
2

As you realized, Grails 2.3 comes with Spock for tests instead of JUnit. I suggest you to look at the basics. If you want class level attributes, look at the "Fields" session.

There's also a repository of examples that you can check. Looking at the service example you can see that your test already have a variable called "service" that Grails define when you use the @TestFor annotation.

@TestFor(NewService)
class NewServiceSpec {

  def "some description of what the test should do"() {
    expect:
      service.serviceMethod() ...
  }
}
Beanpole answered 25/9, 2013 at 11:53 Comment(2)
I changed my test to void "test something"() { expect: service.serviceMethod() } and changed the serviceMethod to return true but I still get | Running 1 unit test... | Running 1 unit test... 1 of 1 | Failure: test something(aspera_web.NewServiceSpec) | java.lang.NullPointerException at aspera_web.NewServiceSpec.test something(NewServiceSpec.groovy:18) | Completed 1 unit test, 1 failed in 0m 5s | Tests FAILED - view reports in C:\Git\aspera_web\target\test-reportsLunate
Share your full test, please.Beanpole

© 2022 - 2024 — McMap. All rights reserved.