Grails code coverage not working - grails

I am using Grails 2.2.4 and create JUnit Test for controller but code coverage not cover my test case of controller below are my test case detail.
//BuildConfig.groovy
plugins {
test ":code-coverage:2.0.3-3"
}
//MyControllerTests.groovy
#TestMixin(GrailsUnitTestMixin)
#TestFor(MyController)
#TestFor([Domain1,Domain2])
class MyControllerTests {
void setUp() {
controller.myService = new MyService()
}
void testAction1(){
controller.action1()
}
}
//mycontroller.groovy
class MyController {
def myService
def action1{
def msg = myService.myFirstAction()
}
}
//myservice.groovy
class MyService{
def myFirstAction(){
//logic which returns string
return 'my logic result'
}
}

Related

Grails - How to instantiate service in Controller when doing controller testing

I am using a service in controller. I am writing unit test for the controller but I am unable to instantiate service in controller. It is always null.
if I instantiate service using new operator in Controller testing class. The services in the service class are not instantiated.
How can I instantiate a service in testing class?
You can let Spring do it for you.
A controller that depends on a service:
// grails-app/controllers/demo/DemoController.groovy
package demo
class DemoController {
def helperService
def index() {
def answer = helperService.theAnswer
render "The answer is ${answer}"
}
}
The service:
// grails-app/services/demo/HelperService.groovy
package demo
class HelperService {
def getTheAnswer() {
42
}
}
A unit test which injects the service:
// src/test/groovy/demo/DemoControllerSpec.groovy
package demo
import grails.test.mixin.TestFor
import spock.lang.Specification
#TestFor(DemoController)
class DemoControllerSpec extends Specification {
static doWithSpring = {
helperService HelperService
}
void "test service injection"() {
when:
controller.index()
then:
response.text == 'The answer is 42'
}
}
A unit test which injects a fake version of the service:
// src/test/groovy/demo/AnotherDemoControllerSpec.groovy
package demo
import grails.test.mixin.TestFor
import spock.lang.Specification
#TestFor(DemoController)
class AnotherDemoControllerSpec extends Specification {
static doWithSpring = {
helperService DummyHelper
}
void "test service injection"() {
when:
controller.index()
then:
response.text == 'The answer is 2112'
}
}
class DummyHelper {
def getTheAnswer() {
2112
}
}

Existing transaction detected in JobRepository - Spring Batch with Grails Plugin

Every time I start my batch job it throws an IllegalStateException and says it detected a transaction in JobRepository. I did some research and removed all #Transactional annotations in my code.
I use the Grails Spring Batch Plugin you can find here, and I work with Grails 2.3.11 and Java 8. My code looks like this:
SimpleJobBatchConfig.groovy
beans {
xmlns batch:"http://www.springframework.org/schema/batch"
batch.job(id: 'simpleJob') {
batch.step(id: 'printStep') {
batch.tasklet(ref: 'printHelloWorld')
}
}
printHelloWorld(SimpleJobTasklet) { bean ->
bean.autowire = 'byName'
}
}
BatchTestController.groovy
class BatchelorController {
def batchTestService
def index() {
}
def launchSimpleJob() {
batchTestService.launchSimpleJob()
}
}
BatchTestService.groovy
class BatchTestService {
def springBatchService
def launchSimpleJob() {
springBatchService.launch("simpleJob")
}
}
SimpleJobTasklet.groovy
class SimpleJobTasklet implements Tasklet {
#Override
RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
println("Hello World!")
return RepeatStatus.FINISHED
}
}
Grails services are transactional by default. You can customize the settings for the whole class or per-method with #Transactional but if you have no annotations it's the same as having a class-scope Spring #Transactional annotation.
To make your service non-transactional, add static transactional = false, e.g.
class BatchTestService {
static transactional = false
def springBatchService
...
}
}

Grails integration test on a service: cannot set property on null object

I am using Grails 2.4.4 for my application, and using spock framework for tests.
class TaxpayerService {
static transactional = false
def springSecurityService
def setImporterDetails(TvfGen tvfGen) {
if (isTrader()) {
String taxPayerCode = springSecurityService?.principal?.getAt("tin")
def importerDetails = HistorizationSupport.withHistorizedFinder(BusinessLogicUtils.getWorkingDate(tvfGen)) {
Company.findByCode(taxPayerCode)
}
if (importerDetails) {
tvfGen.with {
impTaxPayerAcc = taxPayerCode
impName = importerDetails.name
}
}
}
}
}
Here is my integration test:
#Build([TvfGen])
class TaxpayerServiceSpec extends IntegrationSpec {
def taxpayerService
def springSecurityService
void setup() {
}
void tearDown() {
// Tear down logic here
}
void "test set importer details"() {
given:
def tvfGen = TvfGen.build()
springSecurityService = [principal: [tin: '0815790B', authorities: [ROLE_TRADER]]]
taxpayerService.springSecurityService = springSecurityService
taxpayerService.setImporterDetails(tvfGen)
expect:
tvfGen.impName == 'OMNI VALUE'
}
}
As a result I receive an error:
Cannot set property 'springSecurityService' on null object
java.lang.NullPointerException: Cannot set property 'springSecurityService' on null object
at TaxpayerServiceSpec.test set importer details(TaxpayerServiceSpec.groovy:34)

How to write integration test for filter in grails

I have written one filter rule which I want to test using grails integration tests.
Filter is
invalidAccess(controller: "home") {
before = {
redirect(controller: "newHome", action: "index")
return false
}
}
I have followed this link to write the integration test
http://ldaley.com/post/392153102/integration-testing-grails-filters
It returns result as false But gives
null for redirectedUrl
instead of newHome & index method url.
What am I missing here?
import grails.util.GrailsWebUtil
class MyFilterTests extends GroovyTestCase {
def filterInterceptor
def grailsApplication
def grailsWebRequest
def request(Map params, controllerName, actionName) {
grailsWebRequest = GrailsWebUtil.bindMockWebRequest(grailsApplication.mainContext)
grailsWebRequest.params.putAll(params)
grailsWebRequest.controllerName = controllerName
grailsWebRequest.actionName = actionName
filterInterceptor.preHandle(grailsWebRequest.request, grailsWebRequest.response, null)
}
def getResponse() {
grailsWebRequest.currentResponse
}
def testFilterRedirects() {
def result = request( someParameter: "2", "home", "index")
assertFalse result
assertTrue response.redirectedUrl.endsWith(/* something */)
}
}
If you want to try unit testing and need to mock some services then you can mock like:
#TestFor(SomethingToTest)
#Mock([FirstService, SecondService])
class SomethingToTestSpec extends Specification {
and you want integration test then try following test
import grails.util.GrailsWebUtil
import org.junit.After
import org.junit.Before
import org.junit.Test
class MyFilterIntegrationTests {
def filterInterceptor
def grailsApplication
def grailsWebRequest
#Before
void setUp() {
}
#After
void tearDown() {
}
#Test
void testFilterRedirects() {
def result = request("person", "index", someParameter: "2")
assert !result
assert response.redirectedUrl.endsWith('/auth/index')
}
def getResponse() {
grailsWebRequest.currentResponse
}
def request(Map params, controllerName, actionName) {
grailsWebRequest = GrailsWebUtil.bindMockWebRequest(grailsApplication.mainContext)
grailsWebRequest.params.putAll(params)
grailsWebRequest.controllerName = controllerName
grailsWebRequest.actionName = actionName
filterInterceptor.preHandle(grailsWebRequest.request, grailsWebRequest.response, null)
}
}
Ref# Grails Integration Test Filter

Does using #Transactional disable the grails default transaction management

According to the grails docs, services are transactional by default. But, I know you can get more fine grained control of transactions by using the Transactional attribute.
If I have a service such as
class MyService {
#Transactional(...config...)
def method1() { }
def method2() { }
}
My understanding is that in this case, method1 will be transactional, but method2 will not.
If I have
class MyService {
def method1() { }
def method2() { }
}
Then both method1 and method2 will both be transactional.
Is this correct?
If you want your service as transactional set to true the transactional property (this isn't obligatory but if you want to make clear that the service is transactional):
class MyService {
static transactional = true
def method1() { }
def method2() { }
}
If you don't want to:
class MyService {
static transactional = false
#Transactional(...config...)
def method1() { }
def method2() { }
}
Another example (setting transactional property isn't obligatory, but helps to be clear - if you are not the only coding this):
import org.springframework.transaction.annotation.Transactional
class BookService {
#Transactional(readOnly = true)
def listBooks() {
Book.list()
}
#Transactional
def updateBook() {
// …
}
def deleteBook() {
// …
}
}
Another thing you can do is annotate the whole class and override the methods you need to be different:
import org.springframework.transaction.annotation.Transactional
#Transactional
class BookService {
#Transactional(readOnly = true)
def listBooks() {
Book.list()
}
def updateBook() {
// …
}
def deleteBook() {
// …
}
}
Hope this helps ;)
You can disable the Grails default transaction management using withTransaction closure for domains to manage your Transaction manually as follows:
Account.withTransaction { status ->
try {
//write your code or business logic here
} catch (Exception e) {
status.setRollbackOnly()
}
}
If an exception is thrown, then the Transaction will be rollbacked.

Resources