Inject property into integration test Grails 3 - grails

How does one inject properties from the applicaiton.yml file into an integration test in grails 3.0 ?
For ex: I have this property in my applicaiton.yml
----
testing:
defaults:
startUrl: 'http://localhost:8080/'
----
In my Integration Spock test, I have the following code:
class WebpageRolesTestSpec extends Specification {
def grailsApplication
String LOGIN_URL = grailsApplication.config.getProperty('testing.defaults.startUrl')
void "test login screen prompt"() {
expect:
LOGIN_URL == 'http://localhost:8080/'
}
}
The exception i am getting is: Cannot get property 'config' on null object

You could use holders:
import grails.util.Holders
...
LOGIN_URL = Holders.config.testing.defaults.startUrl
...

Below test works for me in Grails 3.1.1, I suppose you would need a clean app.
import grails.test.mixin.integration.Integration
import grails.transaction.*
import spock.lang.*
#Integration
#Rollback
class SampleSpec extends Specification {
def grailsApplication
void "test something"() {
expect:"fix me"
grailsApplication.config.getProperty('testing.defaults.startUrl') ==
'http://localhost:8080/'
}
}

Related

grails restful groovy can not resolve symbol

I am trying to learn grails by following the link: https://guides.grails.org/rest-hibernate/guide/index.html and after creating the controller ProductController as per the page's guidance I am getting the following error:
Unable to resolve class ProductService in ProductController
I new to groovy and trying to resolve the class reference by importing the necessary packages but the link does not show any imports to resolve this class. there is not explicit import statement for ProductService productService in ProductController.groovy. Here are the classes:
ProductController:
package hibernate.example
import groovy.transform.CompileStatic
import grails.rest.*
import grails.converters.*
#CompileStatic
class ProductController extends RestfulController {
static responseFormats = ['json', 'xml']
ProductController() {
super(Product)
}
ProductService productService
def search(String q, Integer max ) {
if (q) {
respond productService.findByNameLike("%${q}%".toString(), [max: Math.min( max ?: 10, 100)])
}
else {
respond([])
}
}
}
ProductControllerSpec:
package hibernate.example
import org.grails.testing.GrailsUnitTest
import spock.lang.Specification
#SuppressWarnings('MethodName')
class ProductControllerSpec extends HibernateSpec implements ControllerUnitTest<ProductController> {
def setup() {
}
def cleanup() {
}
static doWithSpring = {
jsonSmartViewResolver(JsonViewResolver)
}
void 'test the search action finds results'() {
given:
controller.productService = Stub(ProductService) {
findByNameLike(_, _) >> [new Product(name: 'Apple', price: 2.0)]
}
when: 'A query is executed that finds results'
controller.search('pp', 10)
then: 'The response is correct'
response.json.size() == 1
response.json[0].name == 'Apple'
}
}

How to test class with #Autowired using Spock

I have a class in src/groovy like this
public class MyClass {
#AutoWired
SomeOtherClass someOtherClass
String test() {
return someOtherClass.testMethod()
}
}
When I write a test for this method I am getting an error: Cannot invoke method testMethod() on null object.
This is my test :-
def "test test" () {
expect:
myClass.test() == "somevalue"
}
What am I doing wrong? Is there a way to mock the #Autowired class?
You need to mock your someOtherClass. Something like this
def "test test"(){
setup:
myClass.someOtherClass = Mock(SomeOtherClass)
myClass.someOtherClass.testMethod() >> "somevalue"
expect:
myClass.test() == "somevalue"
}
Though the previous answer should work, spock provide more elegant way of injecting beans as per need. You could use doWithSpring closure to declare beans just like spring dsl support provided in grails using resources.groovy.
class MyClass extends Specification{
def setup(){
static doWithSpring={
someOtherClass(SomeOtherClass)
//declare below if want to inject myClass somewhere else as a bean else not
/*myClass(MyClass){bean->
someOtherClass = someOtherClass
}*/
}
}
def "test test" () {
expect:
myClass.test() == "somevalue"
}
}

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
}
}

Grails 3 mail plugin not working

Using Grails 3 it's impossible to get an instance of mailService object, DI is not working:
build.gradle
compile "org.grails.plugins:mail:1.0.7"
testCompile "org.grails.plugins:mail:1.0.7"
application.groovy
environments {
development {
//grails.logging.jul.usebridge = true
grails.plugin.springsecurity.debug.useFilter = true
grails {
mail {
host = "main.mydomain.com"
port = 25
username = "login"
password = "password"
props = ["mail.smtp.auth":"true"]
}
}
grails.mail.default.from="noreply#mydomain.com"
}
production {
grails.logging.jul.usebridge = false
}
}
testController:
import groovy.xml.MarkupBuilder
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.security.access.annotation.Secured
#Secured(["hasRole('PERM_LOGIN')"])
class TestLogController {
def Logger logger = LoggerFactory.getLogger(this.getClass())
def mailService
def index() {
logger.info("Hello");
mailService.sendMail {
to "user#daomain.com"
subject "Hello Fred"
text "How are you?"
}
}
}
The following error occurs:
Caused by NullPointerException: Cannot invoke method sendMail() on null object
->> 18 | index in TestLogController.groovy
So mailService has not been injected properly to cotroller class or to integration test:
import grails.test.mixin.integration.Integration
import grails.util.Holders
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.context.ApplicationContext
import spock.lang.Shared
import spock.lang.Specification
#Integration
class SendMailSpec extends Specification {
#Shared Logger logger
#Shared def mailService
def setup() {
logger = LoggerFactory.getLogger(this.getClass())
ApplicationContext ctx = Holders.grailsApplication.mainContext
mailService = ctx.getBean("mailService");
}
def cleanup() {
}
void "test mailService is not null"() {
expect:
mailService !=null
}
void "test send mail"() {
expect:"mail send"
mailService.sendMail {
to "user#domain.com"
subject "Hello Fred"
text "How are you?"
}
}
}
What is a problem ??
UPDATE: It was wrong mail plugin version, this one works fine:
compile "org.grails.plugins:mail:2.0.0.RC2"
here's the current version (at the moment of writing this) to install :
compile 'org.grails.plugins:mail:2.0.0.RC6'
Here's the link to the main plugin (I don't know why google shows only the old versions) :
https://grails.org/plugins.html#plugin/mail
I hope this helps someone

How to get name of currently running test in spock?

In JUnit 3, I could get the name of the currently running test like this:
public class MyTest extends TestCase {
public void testSomething() {
assertThat(getName(), is("testSomething"));
}
}
How do I do this in spock? I would like to use the test name as a key in a shared resource so that tests don't interfere with each other.
One solution is to leverage JUnit's TestName rule:
import org.junit.Rule
import org.junit.rules.TestName
class MySpec extends Specification {
#Rule TestName name = new TestName()
def "some test"() {
expect: name.methodName == "some test"
}
}
This requires JUnit 4.7 or higher.
For spock 1.0-groovy-2.4 you can try :
def "Simple test"() {
expect:
specificationContext.currentIteration.name == "Simple test"
}

Resources