Grails 2.0.1: Spock test fail with "No bean named 'grailsLinkGenerator' is defined" where redirect is called - testing

I recently upgraded from Grails 1.3.7 to Grails 2.0.1. The application runs normal, but I get into this trouble when cleaning up tests.
All my tests are spock tests. And I updated spock from 0.5-groovy-1.7 to 0.6 when upgrading.
All controller tests that will reach a line of redirect() fail in that line with the same error:
No bean named 'grailsLinkGenerator' is defined
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'grailsLinkGenerator' is defined
Any idea what cause this and how I could fix them?

This started happening for me in a controller unit test by extending spock's ControllerSpec. Switching it back to extend spock.lang.Specification fixed it.
The Spec:
package fileupload2
import static org.junit.Assert.assertThat
import static org.hamcrest.core.Is.is
import spock.lang.Specification;
import grails.test.mixin.TestFor
import grails.plugin.spock.ControllerSpec
#TestFor(FileUploadController)
//class FileUploadControllerSpec extends ControllerSpec {
class FileUploadControllerSpec extends Specification {
def "the index should redirect to create" () {
when:
controller.index()
then:
assertThat(response.redirectedUrl, is('/fileUpload/create'))
}
}
The CUT:
package fileupload2
class FileUploadController {
def fileUploadService
def index() {
redirect (action: "create")
}
def create() {
render(view: 'create')
}
def upload() {
...
}
}
I'm reluctant to say this is a bug as I'm about 2 weeks into this.
Extending UnitSpec seems to work also.

Related

KTor site not reachable

I want to make a simple http server using ktor. However, when I enter the site (127.0.0.1:8080 or 0.0.0.0:8080), it just isn't there. It doesn't print and doesn't respond.
However if I use NanoHttpd instead of ktor, everything works fine. What is my issue?
import io.ktor.application.call
import io.ktor.http.ContentType
import io.ktor.response.respondText
import io.ktor.routing.get
import io.ktor.routing.routing
import io.ktor.server.engine.embeddedServer
import io.ktor.server.netty.Netty
fun main() {
val server = embeddedServer(Netty, port = 8080) {
routing {
get("/") {
println("TEST")
call.respondText("Hello World!", ContentType.Text.Plain)
}
}
}
server.start(wait = true)
}
The output is just:
[main] INFO ktor.application - No ktor.deployment.watch patterns specified, automatic reload is not active
[main] INFO ktor.application - Responding at http://0.0.0.0:8080
It could be one of the following things:
The application code
The run configuration
I am leaning towards there being a problem with the run configuration rather than the application code.
Application code
Even though I think your issue is with the run configuration, in case that it isn't, I'm providing sample code here.
When I use the IntelliJ Ktor plugin, the Ktor app is bootstrapped as follows:
Application.kt
package com.example
import io.ktor.application.*
import io.ktor.http.*
import io.ktor.response.*
import io.ktor.routing.*
fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args)
#kotlin.jvm.JvmOverloads
#Suppress("unused") // Referenced in application.conf
fun Application.module(testing: Boolean = false) {
routing {
get("/") {
call.respondText("Hello, world!", ContentType.Text.Plain)
}
}
}
application.conf
ktor {
deployment {
port = 8080
port = ${?PORT}
}
application {
modules = [ com.example.ApplicationKt.module ]
}
}
I've provided an example Ktor code base here: https://gitlab.com/tinacious/ktor-example
Run configuration
It could be your run configuration in IntelliJ. It needs to be set up as a Kotlin script (and not an Application). When it's set up as an Application, I get the same error you do. Here is how to set up the run configuration I have, allowing me to run the server in IntelliJ:
Add a configuration
Choose Kotlin script from the Templates section. Do not choose Application.
Near the bottom where it says "Use classpath of module" choose your application.main.
Near the top where it says "Main class" you should be able to choose your main application. I found this only showed up after I chose the classpath of the module.
Here are the relevant sections in the configuration:
Here is what I describe in step 4, i.e. I can choose my main class after the class path is added:
The run symbol should be a Kotlin logo:
I would recommend installing the IntelliJ Ktor plugin for bootstrapping your project. It uses Gradle and bootstraps everything so when you run ./gradlew run, you are running it properly and can access it without the manual build configuration step.

Why is my Micronaut Controller bean not handled during tests

I am trying to use micronaut from Kotlin. I have this:
package me.test
import io.micronaut.http.MediaType
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.http.annotation.Produces
#Controller("/hello")
class Controller() {
#Get("/")
#Produces(MediaType.TEXT_PLAIN)
fun ping(): String {
return "hello world"
}
}
package me.test
import io.micronaut.runtime.Micronaut
object Application {
#JvmStatic
fun main(args: Array<String>) {
Micronaut.build()
.packages("me.test")
.mainClass(Application.javaClass)
.start()
}
}
I wrote the following controller test:
package me.test
import io.micronaut.http.client.RxHttpClient
import io.micronaut.http.client.annotation.Client
import io.micronaut.test.annotation.MicronautTest
import org.junit.jupiter.api.Test
import javax.inject.Inject
#MicronautTest(application = Application::class)
class ControllerTest {
#Inject
#field:Client("/")
private lateinit var client: RxHttpClient
#Test
fun `should server ping with a pong`() {
val result = client.toBlocking().retrieve("/hello")
println(result)
}
}
but the test fails with a HttpClientResponseException: Page Not Found.
I have debugged this and from what I can tell, during the test, in DefaultBeanContext.getBeanDefinitions it doesn't find any beans for the #Controller qualifier. When I start the application using my Application class, I can see that it finds the Controller and makes the route available.
This is pretty much the Hello World for Micronaut, I am not sure what's going wrong here.
I think this is purely IDE related. I have Intellij set up to use Annotation Processors, to delegate builds to Gradle and to use the Gradle Test Runner. However, you also need to delete any existing test configurations and then the problem goes away.

Kotlin - Unresolved reference: Dagger{Name}Component

I'm learning how to use Dagger 2 and MVP architeture.
But I'm stuck in this error now:
Unresolved reference: DaggerHelloComponent
Look, this is my module:
#Module
class HelloModule {
lateinit var activityDagger: HelloActivityDagger
constructor(activityDagger: HelloActivityDagger) {
this.activityDagger = activityDagger
}
#Provides
fun providesHelloPresenter(): HelloActivityPresenterDagger = HelloActivityPresenterDagger(activityDagger)
}
and my component:
#Component(modules = [HelloModule::class])
interface HelloComponent {
fun inject(activityDagger: HelloActivityDagger)
}
So when I try to builder this component like this DaggerHelloComponent.create().inject(this) in my HelloActivityDagger shows me the error above.
Anyone know what I am doing wrong?
Cause I can see whats wrong in this code.
Oh, I already have followed this kapt things from this question Unresolved reference DaggerApplicationComponent and nothing happens
EDIT
To be more readable I`ve uploaded my project to Git. https://github.com/luangs7/DaggerMvpExample
Putting this code in the MyApplication class works for me to create the module starting off from your GitHub project - after the first failed build, kapt generates the DaggerHelloComponent class, and I can import it.
import android.app.Application
import br.com.squarebits.mvpexample.DaggerMvp.componentes.DaggerHelloComponent
import br.com.squarebits.mvpexample.DaggerMvp.componentes.HelloComponent
import br.com.squarebits.mvpexample.DaggerMvp.modules.HelloModule
class MyApplication : Application() {
val component: HelloComponent by lazy {
DaggerHelloComponent.builder()
.helloModule(HelloModule(HelloActivityDagger()))
.build()
}
}
If this is not happening at all, you should try the usual debugging steps of restarting Studio with File -> Invalidate Caches / Restart, cleaning and rebuilding your project, etc. Perhaps try pulling the GitHub repo to a new location and see if that builds for you - the code isn't the problem.

Execution failed for task ':compileIntegrationTestGroovy'

I created an application with
grails create-app TestApp
I've created test with
grails create-functional-test Test
When I tried to start test with
grails test-app
It gave me an error:
Execution failed for task ':compileIntegrationTestGroovy'.
The question is how to run tests and solve this problem?
Maybe I've missed some dependencies?
Output is:
* What went wrong:
Execution failed for task ':compileIntegrationTestGroovy'.
org.codehaus.groovy.ast.tools.GenericsUtils.addMethodGenerics(Lorg/codehaus/groovy/ast/MethodNode;Ljava/util/Map;)Ljava/util/Map;
UPD:
grails test-app --stacktrace
returns a long stacktrace with
Caused by: java.lang.NoSuchMethodError:
org.codehaus.groovy.ast.tools.GenericsUtils.addMethodGenerics(Lorg/codehaus/groovy/ast/MethodNode;Ljava/util/Map;)Ljava/util/Map;
UPD
The test is
package myapp
import grails.testing.mixin.integration.Integration
import grails.transaction.*
import geb.spock.*
/**
* See http://www.gebish.org/manual/current/ for more instructions
*/
#Integration
#Rollback
class TestSpec extends GebSpec {
def setup() {
}
def cleanup() {
}
void "test something"() {
when:"The home page is visited"
go '/'
then:"The title is correct"
title == "Welcome to Grails"
}
}
If you are using Grails 3.3.0, there was a problem in the generated test templates so in your integration test you will want to replace this...
import grails.test.mixin.integration.Integration
With this...
import grails.testing.mixin.integration.Integration

How to set CRUD in a subpackage with Play

I am trying to use the CRUD module in subpackages instead of the default one.
package controllers.admin;
import models.Branch;
import controllers.CRUD;
#CRUD.For(Branch.class)
public class Branches extends CRUD {
public static void index() {
render();
}
}
My routes file is:
# Import CRUD routes
* /admin module:crud
However when I use the default url: http://localhost:9000/admin/
I get the template not found error:
Template not found
The template admin/Branches/index.html does not exist.
How can I specify to CRUD module to look for views in the subpackages?
ok. controller was generated with eclipse plugin and included the index() method.
Removing it solved the problem and the module is now working correctly.