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
Related
I am new in Grails, I want to write unit tests for services using Spock. However I have the following issue.
import grails.transaction.Transactional
#Transactional
class BService {
boolean createB(){
return true
}
...
}
For this class I wrote the following test:
class BServiceTest extends Specification {
def "test createB"(){
given:
def service = new BService()
when:
def boolean temp
temp = service.createB()
then:
temp == true
}
}
The error I am getting when I run this test is the following:
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.
and it shows in GrailsTransactionTemplate.groovy:60
I would really appreciatie if anyone can give me a hint.
Add a #TestFor(BService) annotation to your unit test and use the instance of the service that it automatically provides. See http://grails.github.io/grails-doc/3.0.x/guide/testing.html for more information on testing.
Thank you ataylor for your reply. However I did a mistake, so I am now ansewring my own question.
First of all, the name conversion is wrong. When I create a service in grails there is automatically set a unit-test for this, so in that case I would have:
#TestFor(BService)
class BServiceSpec extends Specification {
def setup() {
User u = new User(1)
u.save()
}
def cleanup() {
}
def "test something"(){
}
}
In this case when I write a unit test, it runs.
The test that I had before was a functional test where I could not pass objects from the domain, so I had an error of the transactional manager.
Usually I was ending up writing test cases for a Domain by writing them for constraints and any custom methods(created by us in application) as we know we shouldn't test obvious.
But the time we started using coverage plugin, we found that our domains line of code is not fully covered which was due to gorm hooks(onInsert, beforeUpdate) that we never wrote test cases for.
Is there a way we can test these. One possible way that seems obvious but not suitable is to call another method(containing all code which was earlier in hooks) within these hooks and test that method only and be carefree for hooks.
Any solutions...
Edit
Sample code in domain that I want to unit-test:
class TestDomain{
String activationDate
def beforeInsert() {
this.activationDate = (this.activationDate) ?: new Date()//first login date would come here though
encodePassword()
}
}
How can I unit-test beforeInsert or I would end up writing integration test case?
Perhaps a unit test like:
import grails.test.mixin.TestFor
#TestFor(TestDomain)
class TestDomainSpec extends Specification {
def "test beforeSave"() {
given:
mockForConstraintsTests(TestDomain)
when:
def testDomain = new TestDomain().save(flush:true)
then:
testDomain.activationDate != 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.
In my unit test, I mock a service (which is a ref of the class under test).
Like:
given:
def mockXxService = mockFor(XxService)
mockXxService.demand.xxx(1) {->}
service.xxService = mockXxService
when:
service.yyy()
then:
// verify mockXxService's xxx method is invoked.
For my unit test, I want to verify that mockXxService.xxx() is called. But grails document's mockControl.verify() doesn't work for me. Not sure how to use it correctly.
It is very similar to mockito's verify method.
Anyone knows it?
You are using spock for your unit test, you should be easily able to use spock's MockingApi check invocations:
given:
def mockXxService = Mock(XxService)
service.xxService = mockXxService
when:
service.yyy()
then:
1 * mockXxService.xxx(_) //assert xxx() is called once
You could get more insight about mocking from spockframework docs.
You can even stub and mock that while mocking the concerned service as:
def mockXxService = Mock(XxService) {
1 * xxx(_)
}
If you want Mockito-like behavior in Grails unit tests - just use Mockito. It is far more convenient than Grails' mocking methods.
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