Integration Tests started to fail with grails upgrade - grails

I upgraded a grails app from 1.2.2 to 1.3.7 after this upgrade a few integration tests have started to throw the following error the 'validateAndSaveList' is a method on a service used by the service I'm testing. These tests were passing before the upgrade and they will also pass if I run just the integration test phase with grails test-app -integration
junit.framework.AssertionFailedError:
No more calls to 'validateAndSaveList'
expected at this point. End of
demands.
Code:
import com.e.domain.*
import com.e.exception.GORMServiceException
import com.e.controller.SecurityUserCommand
class AccountServiceTests extends GroovyTestCase
{
def accountService
void testRegisterWithMinimumInfo()
{
def clinic = new Clinic(name:'clinicName')
def securityUserCommand = new SecurityUserCommand(username:'username', password:"password", confirm:"password")
def clinicUser = new ClinicUser(firstName:'fname', lastName:'lname', emailAddress:'abc#abc.com')
clinicUser.clinic = clinic
//clinicUser.securityUser = securityUser
clinic.address = new Address()
// TODO - JsecUser no longer in use
def role = new ShiroRole(name:'TEST')
//def subscription = ESubscription.findByName('Charter Member')
def subscription = new ESubscription(
name:'Charter Member',
description:'Charter Member',
periodType:'Monthly',
numPeriods:12,
amountPerPeriod:25.00,
electronicSubmissionRate:0.00,
accountingRate:0.01,
numAllowedUsers:4,
startDate: today -1,
endDate: today+1
)
subscription.save(flush:true)
if(subscription.hasErrors())
println subscription.errors
assertNotNull subscription
clinicUser.empathicCustomerProfile.subscription = subscription
def result = accountService.register(clinic, securityUserCommand, clinicUser, role)
assert result.success
assert result.clinic.id
assert result.securityUser?.id
assert result.clinicUser.id
}
StackTrace
junit.framework.AssertionFailedError: No more calls to 'validateAndSaveList' expected at this point. End of demands.
at grails.test.MockClosureProxy.doBeforeCall(MockClosureProxy.java:66)
at grails.test.AbstractClosureProxy.call(AbstractClosureProxy.java:74)
at grails.test.GrailsMock$_createMock_closure1.doCall(GrailsMock.groovy:125)
at com.e.service.AccountService.register(AccountService.groovy:46)
at com.e.service.AccountService$register.call(Unknown Source)
at AccountServiceTests.testRegisterWithMinimumInfo(AccountServiceTests.groovy:53)

this answer comes from working the issue out in the comments:
the exception you are getting clearly indicates that somewhere you have put a mock object in your service, and the service is calling the mock object in a way it was not set up to handle.

The root problem as seen from #hvgotcodes is that there was a mock object for the service even though in that given test there was no mocking happening.
This happened in grails 1.3.7
I found a unit test that was doing the following:
def dataBindServiceControl = mockFor(DataBindService)
dataBindServiceControl.demand.safeBind{}
dataBindServiceControl.demand.extractPhones{}
dataBindServiceControl.demand.validateAndSaveList{l-> return true}
def dataBindService = dataBindServiceControl.createMock()
controller.dataBindService = dataBindService
If those tests were removed then all the integration tests would pass so to solve with out rewriting the tests I added the following to the tear down method.
GroovySystem.metaClassRegistry.removeMetaClass(DataBindService)
With this addition the tests are now working correctly in grails 1.3.7

Related

Grails spock service test not calling service method

I'm seeing some strange behavior in a spock test for a service using Grails 2.3.7.
This test works fine:
void "create spot order"() {
given:
def createOrderCommand = newCreateOrderCommand(OrderType.S)
when:
def orderId = service.createOrder(createOrderCommand, user).id.toInteger()
then:
Order.count() == 1
when:
def order = service.orderById(orderId)
then:
// a bunch of assertions
}
This test also works fine:
void "create command with invalid order id"() {
when:
service.commandForOrderId(999)
then:
def exception = thrown(CreateOrderException)
exception.key == "orderService.invalid.order.id"
}
However this test fails - I've set a breakpoint at the beginning commandForOrderId, and it is never hit. command is null (this is where the test fails, on the line checking for null on command), which would never be returned from this service method:
void "create spot command"() {
given:
def createOrderCommand = newCreateOrderCommand(OrderType.S)
when:
def order = service.createOrder(createOrderCommand, user)
then:
Order.count() == 1
when:
def orderId = order.id.toInteger()
def command = service.commandForOrderId(orderId)
then:
command
// a bunch more assertions
}
I've tried removing the #Transactional annotation from the service, using the transactional static field, as well as using neither of these. I've also tried changing the service method to a closure, all with no luck.
I changed the service method to a closure, cleared my target directories, did every manner of clean I know of (within GGTS and grails commands), and the service method started getting hit in the test. I'm still unsure of the actual cause of this error, however.

What is wrong with my Spec?

So, I have this pretty simple Spec below. I have a class that is not a controller or service or anything like that. It's a Job class. It depends on two services: updateService and directoryTypeService. It runs a Redis async job and it's under /grails-app/jobs folder.
All I want is to make sure that whenever I invoke this job#perform() method (which return type is void), a given dependent method called UpdateService#completeClaiming is invoked, but UpdateService#requestNewPin is not. (Listing is a domain class, by the way).
When I run this Spec, I keep getting an error message saying: "No more calls to 'completeClaiming' expected at this point. End of demands."
What am I doing wrong here? Any wild guesses?
#Mock(Listing)
class SubmissionJobSpec extends Specification {
def directoryTypeServiceMock
def updateServiceMock
def job
def setup(){
job = new SubmissionJob()
directoryTypeServiceMock = mockFor(DirectoryTypeService)
updateServiceMock = mockFor(UpdateService)
job.updateService = updateServiceMock.createMock()
job.directoryTypeService = directoryTypeServiceMock.createMock()
}
def "if the directory is enabled and the pin status is ENTERED, we should call updateService.completeClaiming"() {
given:
directoryTypeServiceMock.demand.isUpdateEnabled { DirectoryType d, Country c -> return true}
new Listing(
location: new Location(country: Country.DE)
).save(failOnError: true, validate: false)
when:
job.perform(Listing.last().id, true)
then:
1 * updateServiceMock.completeClaiming(Listing.last(), true) >> new ListingEvent(output: [success: true])
0 * updateServiceMock.requestNewPin(_ as Listing, true)
}
You seem to be confusing Groovy and Spock mocks. You can't use Spock mocking syntax (e.g. 0 * updateServiceMock.requestNewPin(_ as Listing, true)) for a Groovy mock created with mockFor(). Spock mocks are created using Mock(), Stub() or Spy(). I'm not aware of any good reason to use a Groovy mock in a Spock spec.

Grails 2.4 upgrade issues from 2.2 test event called at app startup

At application startup the eventTestPhasesStart event code in _events script is being called. The test classes referenced in the event code are not available when executing runapp which leads to classes not resolved errors at startup.
unable to resolve class org.codehaus.groovy.grails.test.spock.GrailsSpecTestType
unable to resolve class - org.codehaus.groovy.grails.test.junit4.JUnit4GrailsTestType
unable to resolve class org.codehaus.groovy.grails.test.runner.phase.IntegrationTestPhaseConfigurer
This code also fails to run in forked mode which has forced us to turn forked mode off to run the integration tests which means we cannot use the debugger to debug tests as Grails 2.4 now requires.
The following is the event code:
eventTestPhasesStart = {phasesToRun ->
println "setting inmem phase"
phasesToRun << "inmem"
def inmemPhaseConfigurer = new IntegrationTestPhaseConfigurer(projectTestRunner.projectTestCompiler, projectLoader)
projectTestRunner.testFeatureDiscovery.configurers.inmem = inmemPhaseConfigurer
def inmemtestTypeName = "inmem"
def inmemtestDirectory = "inmem"
def inmemtestMode = new GrailsTestMode(autowire: true, wrapInTransaction: true, wrapInRequestEnvironment: true)
inmemTestTypes = []
inmemTestTypes << (new GrailsSpecTestType(inmemtestTypeName+"Spock", inmemtestDirectory, inmemtestMode))
inmemTestTypes << (new JUnit4GrailsTestType(inmemtestTypeName+"JUnit", inmemtestDirectory, inmemtestMode))
projectTestRunner.testFeatureDiscovery.testExecutionContext.inmemTests = inmemTestTypes
}
When running in forked mode this event is again called when/where it shouldn't resulting in the dynamic properties such as projectTestRunner not being found.
Is there a way to prevent this script from being executed when it shouldn't?
thank you

integration testing in Grails: what is the correct way?

I'm entirely new to Grails and it's testing functions since I started my current job approx 4 months ago. The person who trained me on testing left our group several weeks ago, and now I'm on my own for testing. What I've slowing been discovering is that the way I was trained on how to do Grails integration testing is almost entirely different from the way(s) that I've seen people do it on the forums and support groups. I could really use some guidance on which way is right/best. I'm currently working in Grails 2.4.0, btw.
Here is a sample mockup of an integration test in the style that I was trained on. Is this the right or even the best way that I should be doing it?
#Test
void "test a method in a controller"() {
def fc = new FooController() // 1. Create controller
fc.springSecurityService = [principal: [username: 'somebody']] // 2. Setup Inputs
fc.params.id = '1122'
fc.create() // 3. Call the method being tested
assertEquals "User Not Found", fc.flash.errorMessage // 4. Make assertions on what was supposed to happen
assertEquals "/", fc.response.redirectUrl
}
Since Grails 2.4.0 is used, you can leverage the benefit of using spock framework by default.
Here is sample unit test case which you can model after to write Integration specs.
Note:
Integration specs goes to test/integration
should inherit IntegrationSpec.
Mocking is not needed. #TestFor is not used as compared to unit spec.
DI can be used to full extent. def myService at class level will inject the service in
spec.
Mocking not required for domain entities.
Above spec should look like:
import grails.test.spock.IntegrationSpec
class FooControllerSpec extends IntegrationSpec {
void "test a method in a controller"() {
given: 'Foo Controller'
def fc = new FooController()
and: 'with authorized user'
fc.springSecurityService = [principal: [username: 'somebody']]
and: 'with request parameter set'
fc.params.id = '1122'
when: 'create is called'
fc.create()
then: 'check redirect url and error message'
fc.flash.errorMessage == "User Not Found"
fc.response.redirectUrl == "/"
}
}

Grails Quartz Job Integration test - Not autowired Job

I'm writing the Integration test for a Quartz Job in a grails application.
I've the Job in grails-app/jobs folder, and if I start the application it works. The problem is that I want to get it in an integration test, but the autowire won't work. The test is like:
class MyJobTest{
MyJob myJob
def setUp(){
assert myJob != null
}
def testExecute(){
//test logic
}
}
but it fails because myJob is null...some help?
Quartz Jobs are not autowired like services are under the test environment. The documentation for the Quartz job also explicitly states that by default it will not execute on schedule under the test environment (you could change that if you want to but I wouldn't). I would just instantiate myJob = new MyJob() in your setUp and call the execute() method to test it. If you're trying to test the triggers you may want to find a way to look at what is inside the triggers {} maybe inspecting the metaClass?
EDIT IN RESPONSE TO COMMENT:
I've never gotten the services out of the application context so that might work. The way I would probably test it is as follows:
Assuming your class looks something like this:
class MyJob {
def myServiceA
def myServiceB
def execute() {
if(myJobLogicToDetermineWhatToDo) {
myServiceA.doStuff(parameter)
} else {
myServiceB.doStuff(parameter)
}
}
}
What you're really wanting to test here is the myJobLogicToDetermineWhatToDo. I would assume that you have (or can easily write) integration and/or unit tests against your services myServiceA and myServiceB to ensure that they are working correctly. I would then write unit tests to test the logic/wiring of your Job to the appropriate service.
#Test
void routeOne() {
def job = new MyJob()
def myServiceA = new Object()
def expectedParameter = "Name"
def wasCalled = false
myServiceA.metaClass.doStuff = {someParameter ->
assert expectedParameter == someParameter
wasCalled = true
}
job.myServiceA = myServiceA
//Setup data to cause myServiceA to be invoked
job.execute()
assert wasCalled
}
Then repeat this process for all of the routes you have through your Job. This way you can isolate your tests down to the smallest part possible and test the logic of the object that you're invoking not the services it is using. I would assume you're using a service because the logic in there is being used by another part of the system. If you're testing the service through this job and for some reason the job goes away then you have to re-write your tests to invoke the service directly. The way that I've proposed you have tests testing the service directly and tests that mock out those service calls. If the job goes away you would simply delete the tests associated with it and you won't loose any test coverage. Kinda long winded but that's how I would approach testing it.

Resources