Grails Unit Test - unit-testing

I have unit test wich extends GrailsUnitTestCase :
import grails.test.GrailsUnitTestCase
class HttpdParserSpec extends GrailsUnitTestCase {
}
However I saw in Grails documentation that is deprecated.
I tried to use the following :
import grails.test.mixin.TestFor
#TestFor(HttpdParser)
class HttpdParserSpec {
}
I obtain the following error :
Cannot add Domain class [class fr.edu.toolprod.parser.HttpdParser]. It
is not a Domain!
It's true.It's not a Domain class.I only want test a simple class HttpdParser.
What am I doing wrong ?
So how to make a simple unit test ? Have you an example ?

Don't use the TestFor annotation. Just write a unit test as you normally would. TestFor is useful for rigging up Grails artifacts and relevant elements of the environment for unit testing them.
class HttpdParserSpec extends spock.lang.Specification {
void 'test something'() {
when:
def p = new HttpdParser()
p.doSomething()
then:
p.someValue == 42
}
}

You can also just use the #TestMixin annotation with the GrailsUnitTestCaseMixin like this:
import grails.test.mixin.support.GrailsUnitTestMixin
import grails.test.mixin.TestMixin
#TestMixin(GrailsUnitTestMixin)
class MyTestClass {}

Related

Grails Unit Test does not work when dependency inject is necessary

I am trying to run my unit tests in Grails 4.0.3 through the command grails test-app.
Unfortunately I am in trouble with dependency injection.
I have basically two test cases. The first one does not work with the response No GORM implementations configured. Ensure GORM has been initialized correctly It seems that PidService is not correctly injected.
To demonstrate my suspicion I created a private method which only throws an exception, to be invoked in the second test case. So, I invoked that method in the second one and it worked as expected. The exception was correctly catched and I could verify that the message is correct.
package br.gov.cmb.pid.tests
import br.gov.cmb.pid.services.PidService
import grails.testing.services.ServiceUnitTest
import org.grails.web.json.JSONObject
import spock.lang.Specification
class PidIssuingSpec extends Specification implements ServiceUnitTest<PidService> {
def setup() {
}
def cleanup() {
}
def "Test that injection is not working"() {
given:
JSONObject wrongPidIssuingDocument = new JSONObject()
when:
service.buildPidIssuingOrder(wrongPidIssuingDocument)
then:
def e = thrown(Exception)
e.message == "Register number is mandatory."
}
def "Test that works because no injection is necessary"(){
when:
dispException()
then:
def e = thrown(Exception)
e.message == "Register number is mandatory."
println(e.message)
}
private void dispException(){
throw new Exception("Register number is mandatory.")
}
}
Grails Unit Test does not work when dependency inject is necessary
In general unit tests that require dependency injection is supported.
See the Modifying the Application Context section at https://testing.grails.org/2.4.1/guide/index.html#unitTesting. That demonstrates how to add beans to the context in a unit test so they may be injected. For example, you could do this:
Closure doWithSpring() {{ ->
// create a bean named "someService" which
// is an instance of SomeService.
// the someService bean may be injected into the
// the class under test
someService(SomeService)
}}
At https://github.com/grails/grails-testing-support/blob/9f782ff3b911919e421440feb8a2e4736c6aced6/examples/demo33/src/test/groovy/demo/ReportingServiceSpec.groovy is a working example:
package demo
import grails.testing.services.ServiceUnitTest
import spock.lang.Specification
class ReportingServiceSpec extends Specification implements ServiceUnitTest<ReportingService> {
Closure doWithSpring() {{ ->
someHelper RushHelper
}}
void "test dependency injection"() {
expect:
service.retrieveSomeNumber() == 2112
}
}
class RushHelper implements MathHelper {
#Override
int getSomeNumber() {
2112
}
}
Notice that the service being tested is the ReportingService. The RushHelper is being injected into that service to support the test.

Tests pass with Playframework 1.2.x but fails with Playframework 1.4.x

I am migrating my application from Play1.2+Java7 to Play1.4+Java8
Play1.2+Java7 my test passes OK
Play1.4+Java8 my test fails.
I have reduced the code to the minimum and reproduced the problem. Here is the main line
The model is
package models;
import play.db.jpa.Model;
import javax.persistence.Entity;
#Entity
public class Token extends Model {
public String name;
public String role;
}
The controller is
package controllers;
import models.Token;
import play.mvc.Controller;
public class Application extends Controller {
public static void index() {
renderJSON(Token.all().fetch());
}
}
The DB test configuration is
%test.application.mode=dev
%test.db.url=jdbc:h2:mem:play;MODE=MYSQL;LOCK_MODE=0
%test.jpa.ddl=create
The test is
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.junit.*;
import org.junit.Before;
import play.test.*;
import play.mvc.*;
import play.mvc.Http.*;
import models.*;
public class ApplicationTest extends FunctionalTest {
#Before
public void before() {
Token.deleteAll();
}
#Test
public void testThatIndexPageWorks() {
{
Response response = GET("/");
assertIsOk(response);
String content = getContent(response);
System.out.println(content);
assertFalse(content.contains("le nom"));
assertFalse(content.contains("identifier"));
}
Token t = new Token();
t.name="le nom";
t.role="identifier";
t.save();
{
Response response = GET("/");
assertIsOk(response);
String content = getContent(response);
System.out.println(content);
assertTrue(content.contains("le nom"));
assertTrue(content.contains("identifier"));
}
}
}
The behaviour is not predictable. It seems that saving entities in the tests are committed async and calling the controller depends on the threads while it did not in release 1.2
I can provide the whole project if necessary
As I do not want to use the fixtures, I have to manually sync the DB: test call of model.save() is done within a local transaction. The transaction is not closed when GET is called. the data is not flushed yet.
I thought that it was covered by
jpa FlushModeType COMMIT
It seems that it is the case in 1.2.x, but not the case in 1.4.x
I modified the test adding the code snippet below after save() and deleteAll(), and it works fine
if ( play.db.jpa.JPA.em().getTransaction().isActive()) {
play.db.jpa.JPA.em().getTransaction().commit();
play.db.jpa.JPA.em().getTransaction().begin();
}

how to assert values inside "render" in unit test case (grails ,junit)

I was trying to assert the values inside "render" in my unit test cases written in Grails. But it does not seems to be proper
render(view:"create",model[:])
what i tried was
assertEquals("create",renderArgs("view"))
i also tried some alternatives like controller.response.renderedUrl etc. But none of those are working.
Could someone give an idea?
Thanks in advance,
BK
To test the view you can simply use an implicit view variable, though it will point to the path of your view/template, e.g. /controller/create. So you could write assertEquals(view, '/controller/create'). There is also an implicit model variable for which you can proceed similarly.
See docs (Testing View Rendering section).
The following tests work:
grails-app/controllers/demo/DemoController.groovy:
package demo
class DemoController {
def index() {
render view: 'first'
}
}
test/unit/demo/DemoControllerSpec.groovy:
package demo
import grails.test.mixin.TestFor
import spock.lang.Specification
#TestFor(DemoController)
class DemoControllerSpec extends Specification {
void "test render view"() {
when:
controller.index()
then:
'/demo/first' == view
}
}
test/unit/demo/DemoControllerTests.groovy:
package demo
import grails.test.mixin.TestFor
#TestFor(DemoController)
class DemoControllerTests {
void testRenderView() {
controller.index()
assert '/demo/first' == view
}
}
I hope that helps.

Grails integration test - redirect action returns null

This is a small integration Junit that I'm having difficulty with. I've re-written this several different ways and the current way is straight out of the Grails manual - but it still returns null. I don't see the error; I thought it might be a spelling error but I've checked all those. I've tried redirectUrl and redirectedUrl - still returns null.
Controller snippet:
#Transactional(readOnly = true)
def saveReportError() {
redirect(action:'reportError')
}
Test:
#Test
void "test save error report"() {
controller.saveReportError()
assertEquals '/reportSiteErrors/reportError', controller.response.redirectUrl
}
I recommend to implement the test as a unit test like this.
import grails.test.mixin.TestFor
import spock.lang.Specification
#TestFor(SimpleController)
class SimpleControllerSpec extends Specification {
void 'test index'() {
when:
controller.index()
then:
response.redirectedUrl == '/simple/hello'
}
}
Using a unit test has the advantage of speed.

How to run scala tests with junit 4?

I can't run following code with IDEA
#Test
class CompanyURLTest extends Assert {
#Test
def test = assert(false);
}
It runs, but J-Unit says that there are not test to run
I generally use ScalaTest in combination with the Junit4 runner so that Maven sees and executes my tests. I like the Spec/FlatSpec/WordSpec semantics for organizing tests. I'm experimenting with the ShouldMatchers but I have used JUnit for so long that asserts just seem a bit more natural to me.
Here's an example:
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import org.scalatest.FlatSpec
import org.scalatest.matchers.ShouldMatchers
#RunWith(classOf[JUnitRunner])
class BlogFeedHandlerTest extends FlatSpec with ShouldMatchers with Logging {
"the thingy" should "do what I expect it to do" in {
val someValue = false;
assert(someValue === false)
}
}
The ScalaTest docs are at http://www.scalatest.org/
The following works for me
import org.junit._
import Assert._
class MyTest {
#Test
def test = assert(false)
}
The #org.junit.Test annotation is only applicable for methods: #Target({ElementType.METHOD}).
Also keep in mind that test methods must return Unit.
import org.junit.Assert._
import org.junit.Test
class CompanyURLTest {
#Test def test = assertFalse(false)
}
Even though it's late - Gradle site surprisingly has a lot of good tutorials showing how to support Scala tests.
https://guides.gradle.org/building-scala-libraries/#review_the_generated_project_files