I have existing UnitTests written extending grails' GrailsUnitTestCase. I wrote new Unit Tests using Spock framework. Running individual Spock Spec with following command is fine.
prayag#prayag:~/gccount$ grails test-app spock: ChronicSpec
But running existing UnitTests throws compilation error in Spock Tests.
prayag#prayag:~/gccount$ grails test-app unit: ChronicUnitTest.testDefaultChronic
| Error Compilation error compiling [unit] tests: startup failed:
/home/prayag/gccount/test/unit/com/zazzercode/chronic/ChronicSpec.groovy: 45: unexpected token: } # line 45, column 5.
} //end of response process
^
1 error
ChronicSpec.groovy is as below
class ChronicSpec extends Specification {
final public String CHRONIC_DEFAULT_METRIC = ReportType.CHRONIC_REPORT + Constants.COLON + ChronicMetrics.DEFAULT
final public String INDEX_NAME = "gccount"
ChronicService chronicService
void "when response is processed json should be created"() {
given:
def contentBuilder = XContentFactory.jsonBuilder().startObject()
chronicService = new ChronicService()
//other code goes here
when:
listener.writeJson(records, contentBuilder, "chronic")
then:
//assertion goes here
} //end of response process => this is where exception is thrown
}
Tools 'm using
grails : 2.2.3
spock : 0.7
I am surprised this actually compiles, you cannot leave an empty "then:" block.
You need at least one assertion. As suggested by Sergio Michels, add an assertion and it should fix it.
Related
I am doing my unit testing using spock framework. I am using stub to do my test. my unit test gave me success but when I checked my code coverage that is showing that code has not been included. Is it expected behaviour? if not how to resolve this?
below is my spcok framework code
class ConfigurationLoaderTest extends Specification {
def "loadConfigurationTest" (){
given:
ConfigurationLoader configLoader = Stub()
when:
def rpcApiInfo= configLoader.loadConfiguration();
then:
rpcApiInfo != null
}
}
when I ran it it showing test case passed but my code coverage is still 0 for 'loadConfiguration' method
In Grails 3.1.12, I want to unit test a service:
#Transactional
class PlanService {
List<Plan> getPlans(Map params) {
def currentUser = (User)springSecurityService.getCurrentUser()
return Plan.findAllByCompany(currentUser.employer, params)
}
}
Like this:
#TestFor(PlanService)
#Mock([Plan, User, Company])
class PlanServiceSpec extends Specification {
void "Retrieve plan from the current user"() {
setup:
// create and save entities here
when: "the plans are retrieved"
def params = null
def plans = service.getPlans(params)
then: "the result should only include plans associated to the current user's company"
plans.size() == 2
}
Running the test from the console:
grails> test-app my.PlanServiceSpec -unit
Fails with:
my.FundingPlanServiceSpec > Retrieve plan from the current user FAILED
java.lang.IllegalStateException at PlanServiceSpec.groovy:48
and in the test report (HTML):
java.lang.IllegalStateException: No transactionManager was specified.
Using #Transactional or #Rollback requires a valid configured transaction manager.
If you are running in a unit test ensure the test has been properly configured
and that you run the test suite not an individual test method.
Now if I comment out the #Transactional annotation in the service, the test passes, but that's not the intended implementation. I am able to work around the problem by mocking the transaction manager:
service.transactionManager = Mock(PlatformTransactionManager) {
getTransaction(_) >> Mock(TransactionStatus)
}
But this seems very awkward, if not wrong.
Is there some incantation I forgot to invoke?
EDIT: looks similar to an old bug, but it's been closed more than a year.
Have you tried what a comments says that fixes the problem? If not, try to annotate the test class with:
#TestMixin(DomainClassUnitTestMixin)
and then:
service.transactionManager = getTransactionManager()
Was getting the same error in grails 3.3.2 when trying to test transactional service.
adding DataTest interface solved the issue for me.
class HelloServiceSpec extends Specification implements ServiceUnitTest<HelloService>, DataTest {
}
I have used manually written as well as Grails generated Unit tests for this command object:
package myapp
#grails.validation.Validateable
class SearchCommand {
String basisBuild
String buildToSearch
static constraints = {
basisBuild(blank: false)
}
}
After having my hand written unit test fail I used Grails:
create-unit-test myapp.SearchCommand
I filled in the Unit Test, and made an assertion that should pass per documentation on mocked constraints:
package myapp
import static org.junit.Assert.*
import grails.test.mixin.*
import grails.test.mixin.support.*
import org.junit.*
#TestMixin(GrailsUnitTestMixin)
class SearchCommandTests {
void setUp() {
mockForConstraintsTests(SearchCommand)
}
void tearDown() {
// Tear down logic here
}
void testSomething() {
SearchCommand commandUnderTest = new SearchCommand()
commandUnderTest.validate(basisBuild: "")
assertEquals "blank", commandUnderTest.errors['basisBuild']
}
}
Why am I getting this failure?
grails> test-app
| Running 9 unit tests... 9 of 9
| Failure: testSomething(com.siemens.soarian.sf.gap.SearchCommandTests)
| java.lang.AssertionError: expected:<blank> but was:<null>
at org.junit.Assert.fail(Assert.java:93)
I believe I found the grails supported way to unit test Command objects in grails 2.0. You need to use mockCommandObject provided by the ControllerUnitTestMixin.
Credit to Erik
http://www.jworks.nl/2012/04/12/testing-command-objects-in-grails-2-0/
EDIT
Using validate() appropriately and mockForConstraintsTest should work if the patch mentioned in the existing Grails bug is in place (Thanks to #codelark for bringing that up). In order to test the command object from a Web App standpoint (using controller) the below information would be helpful.
Test Command Object Using Controller action:-
A command object is only deemed as such when it is used as a parameter in one of the action method inside a controller. Refer Command Objects (Warning NOTE).
Use SearchCommand in an action method, you should be able to assertEquals.
Sample:
void testSomething() {
YourController controller = mockController(YourController) //Or instantiate
SearchCommand commandUnderTest = new SearchCommand ()
//Note the usage here. validate() does not take parameters
commandUnderTest.basisBuild = ''
commandUnderTest.validate()
//Call your action
controller.searchCommandAction(commandUnderTest)
assert response.text == 'Returned'
assertEquals "blank", commandUnderTest.errors['basisBuild']
}
YourController's action:-
def searchCommandAction(SearchCommand sc){
render "Returned"
}
Note:
With out the patch from the grails bug we see the below error in #Grails 2.1.4, 2.2.0 & 2.2.1
I get an error when I only correct the validation and use mockForConstraintTests without using controller action:
You are using the validate method incorrectly. You never set the field on the class, so the field is null, not blank. Try changing your test as follows:
void testSomething() {
SearchCommand commandUnderTest = new SearchCommand()
commandUnderTest.basisBuild = ""
assertFalse commandUnderTest.validate()
assertEquals 'blank', commandUnderTest.errors['basisBuild']
}
Edit: There is also a grails bug when testing command classes that use the #Validatable annotation. There are some workarounds in the bug commentary.
When I try to test for a thrown exception using the following code:
#TestFor(EncryptionService)
class EncryptionServiceSpec extends Specification {
def "test decryption of unecnrypted file"(){
setup:
def clearTextFile = new File("test/resources/clearText.txt")
clearTextFile.write("THIS IS CLEAR TEXT")
when:
def (privateKey,publicCert) = service.generateKeyPair("123")
service.decryptFile(new FileInputStream(clearTextFile), privateKey )
then:
clearTextFile.delete()
thrown GeneralSecurityException
}
}
I get the following compilation exception when I run either grails test-app -unit
Unexpected error during compilation of spec 'com.genospace.services.EncryptionServiceSpec'. Maybe you have used invalid Spock syntax? Anyway, please file a bug report at http://issues.spockframework.org.
java.lang.ClassCastException: org.codehaus.groovy.ast.expr.ArgumentListExpression cannot be cast to org.codehaus.groovy.ast.expr.VariableExpression
at org.codehaus.groovy.ast.expr.DeclarationExpression.getVariableExpression(DeclarationExpression.java:103)
at org.spockframework.compiler.SpecRewriter.moveVariableDeclarations(SpecRewriter.java:538)
Try without leveraging Groovy's multi-assignment feature (def (privateKey,publicCert) = ...). If this solves the problem (and I think it will), please file an issue at http://issues.spockframework.org.
When migrating from Grails 2.0.0 to 2.1.2 some of our tests started failing with NullPointerException (the same behavior is observed with Grails 2.0.3)
Here are snippets of code enough to reproduce the issue.
The controller:
class TestController {
def test() {
render(template: "/test")
}
}
The unit test:
import static org.junit.Assert.*
import grails.test.mixin.*
import grails.test.mixin.support.*
import org.junit.*
import grails.test.mixin.web.GroovyPageUnitTestMixin
#TestMixin(GroovyPageUnitTestMixin)
#TestFor(TestController)
class TestControllerTests {
void test_paramsAndSession_Null() {
controller.test()
def result = response.text
print result
assert render(template: "/test") == result
}
}
The template _test.gsp:
Params and session test.
Params(<%params.id1%>)<br/>
Session(<%session.id2%>)<br/>
With Grails 2.0.0 the application and the test work fine.
With Grails 2.1.2 the application still works fine, but the test starts failing with NullPointerException:
java.lang.NullPointerException: Cannot get property 'id1' on null object
at D__Eclipse_Workspace_paramsAndSessionTest_grails_app_views__test_gsp.run(_test.gsp:2)
at TestController.test(TestController.groovy:4)
at TestControllerTests.test_paramsAndSession_Null(TestControllerTests.groovy:12)
java.lang.NullPointerException: Cannot get property 'id2' on null object
at D__Eclipse_Workspace_paramsAndSessionTest_grails_app_views__test_gsp.run(_test.gsp:3)
at TestController.test(TestController.groovy:4)
at TestControllerTests.test_paramsAndSession_Null(TestControllerTests.groovy:12)
(The second exception appears when fix (1) below is applied)
What is the reason for that?
I see I can fix the test making the following changes:
params.id1 -> params?.id1 (1)
session.id2 -> session?.id2
But this does not look like a valid solution (changing my application for unit tests to work).
Please help me understand whether I am doing something wrong or there is a bug in Grails.
UPDATE: I've submitted a bug http://jira.grails.org/browse/GRAILS-9718