controllers integration test grails3: services are not getting injected - grails

I am upgrading a grails app from 2.4.3 to 3.0.8.
There are a lot of integration tests which are using grails.util.GrailsWebUtil.bindMockWebRequest(grailsApplication.mainContext) following by controller.method call. But I discovered that grails.util.GrailsWebUtil doesn't contain bindMockWebRequest method anymore, seems like it has been replaced with grails.util.GrailsWebMockUtil, alright, but all services declared in controller are not getting injected into the class. I could use grails.test.spock.IntegrationSpec but this class has also been removed from grails3. There is a suggestion to use functional tests for integration test of controllers, but this solution doesn't work for me, I'm not itching to implement all these tests as functional, or inject dependencies manually into controller instances, how can I fix it?

Use grails.test.mixin.integration.Integration annotation instead of grails.test.spock.IntegrationSpec class extension.
And move the integration tests to src/integration-test/groovy.

I'm upgrading from Grails 2.5.1 to 3.2.4. One of my integration tests could not find the service I injected with def xxxService. I included the service in the #Mock list. XxxServiceIntegrationSpec extends Specification.
I know this does not quite relate to testing controllers, but maybe it helps?

We had dozones of controller integration in our old grails 2.x app. When we migrated to grails 3, we wanted to keep it, can not throw them and write functional tests from scratch.
Here I have blogged about it Integration testing controllers with Grails 3
The basic steps are
- setup mock request and response
- set current controller name
- rest mock request and response at the end of the test
See the above blog post for a complete example.
Hope it helps.

For anyone still looking for a solution to this (I had the same problem), I found this example really useful:
https://github.com/albertodeavila/testingGrails3

Related

Run controller test on two different Rails applications

I'm helping to migrate a Rails 2 app to Rails 4, and I have come in towards the end of the project. The Rails 2 app has no tests.
Obviously we need tests to make sure the Rails 4 app works, but we don't want to write the tests in Rails 2 syntax, and then go through the pain of migrating the tests to Rails 4. We currently use RSpec on other projects.
I thought of writing them in Rails 4 as feature tests, and using Capybara.app_host to re-route the requests to a running Rails 2 application instance. Problem is, that the application is an API, and Capybara is not meant for testing APIs.
Is there any way of routing RSpec controller tests to another server instance?
Thanks again for the comments.
I think we have a plan. We tried to get cucumber and cucumber-api-steps running on our old project, but we realised that it was going to be hard work getting old gem versions to work nicely together.
The solution I'm trying now is using RSpec 1.3 and creating a spec/requests folder and adding controller tests to it.
I got this idea from a post from http://matthewlehner.net/rails-api-testing-guidelines/ - thanks Matthew. I don't see request specs in the docs until RSpec 2, so we make our controller tests pretty close to integration tests using integrate_views, then check the contents of the body returned by the controller.
As for the syntax, maybe we can include an expect(..) helper to return an object that calls #should from a #to method in the Rails 2 project and remove it when we port the Rails 4 project.

combine #TestFor and #Integration Annotation grails 3

I migrate a large Grails 1.3.7 project to 3.1.6.
Tests for Controllers are integration tests. This works fine because the tests inherit from ControllerSpec. Now i´m should be able to do something like this:
#Integration
#TestFor(SampleController)
class SampleControllerIntSpec extends Specification {
Because the TestFor Annotation allows usage of model/view/.. fields like in Unit tests.
Is there a way to do something like this?
Thanks in advance.
No the TestFor annotations are exclusively for unit tests, Integration tests are full functional tests in Grails 3 where you should use a client like Geb to send requests to the server and assert responses.

Where is IntegrationSpec in Grails 3

In middle of upgrading to Grails 3.0.1. All good except for integration testing which worked well in 2.4.4.
I've noticed grails.test.spock.IntegrationSpec is not there in org.grails:grails-test:3.0.1 any more.
Tried extending spock.lang.Specification and running via Gradle integrationTest task however it didn't seems to inject Spring resources. Also tried #Integration getting same error, additionally complained by GGTS:
General error during canonicalization: Provider "data" not installed java.nio.file.FileSystemNotFoundException: Provider "data" not installed at java.nio.file.Paths.get(Paths.java:147) at
org.grails.io.support.MainClassFinder.searchMainClass(MainClassFinder.groovy:37) at
org.grails.compiler.injection.test.IntegrationTestMixinTransformation.visit(IntegrationTestMixinTransformation.groovy:82) at
org.codehaus.groovy.transform.ASTTransformationVisitor.visitClass(ASTTransformationVisitor.java:150) at org.codehaus.groovy.transform.ASTTransformationVisitor
...
So I'm wondering if IntegrationSpec still exists in 3.0. How should I get it work?
Alright, figured out #Integration should be applied and to resolve the compilation error I had to specify #Integration(applicationClass = Application.class) because somehow the IDE couldn't find Application class. Of course the test case should extend Specification.
#Autowired to be used for objects that need to be injected into your test classes. Can't use #Autowired in conjunction with #Shared, which you can do in 2.x.

How to test a Rails engine that depends on its hosting application?

I have a rails application, and I'm trying to split the code into several engines.
The main application Holds one main controller - Api::ApplicationController, and all the controllers in the engines inherit from that controller, for example:
Api::Products::ProductsController < Api::ApplicationController
I use RSpec for testing.
When I run the application everything works just perfect, but when I try to run the engine's Rspecs, I get an error:
uninitialized constant Api::ApplicationController
As you understand the engine cannot work separately from the application, so I tried to stub Api::ApplicationController inside the spec (products_controller_spec.rb), but it fails before it even starts to run the spec.
I thought maybe I should Implement it in a different way, and inject ApplicationController functionality somewhere instead of inherit from it, but I don't know where.
Another thing I considered, is to inject the engine's specs into the hosting application and run it from there, but it doesn't seem to work, and it is not possible to debug the specs that way.
How can I test it?
Rails Engines create small dummy applications for testing purposes. You need to create a minimal application that has the features you need to test your application, and it will use this to run it's specs.
See here:
http://edgeguides.rubyonrails.org/engines.html#testing-an-engine
A better solution for this case I think is to put shared application code that all the engines share as modules in a shared gem that all your engines can include.

Grails 2.0.1 controller action methods have stopped working

My project has always used grails 2.0.1 and my controllers define their actions as methods not closures. Previously these actions have always worked (i.e. the browser can render the correct gsp page first going through the action method in the controller).
Recently we've noticed that the bespoke actions no longer work, the browser reports a '404 resource not found'. We're still on grails 2.0.1, this is confirmed by 'loading grails 2.0.1' comments in every grails command that is run. Although there are some controller/domain/services changes, none of those changes should affect the use of action methods. From what I can tell, we've not downgrade the version of grails/groovy.
If I change the actions to be defined as closures, then it works fine. But I'm not happy with this as my solution as methods are the preferred way and it used to work.
I've tried the usual approach to grails weirdness: proper clean and rebuild, but no joy. Also, this is an issue in both eclipse and unix envs (project delivered as a war run by the grails command), so it must be something in the project files but I cannot spot anything that has changed.
Any suggestions what could have happened to my project and how to resolve?
I've finally tracked my problem down to an aspect I was using to monitor long running method calls. I had changed the pointcut to include 'within(com.mydomain.domain..*)' which is where my Controller class resides. This appeared to stop my bespoke links from working, not entiring sure why. I hadn't intended this, I just wanted my pointcut to include all domain class methods but I'm happy to sacrifice that in order to get controller method actions working again.
I've resolved this issue by amending my pointcut.

Resources