Get config of other environment in Grails 2.* - grails

I'm running Grails 2.1.1, and i'm looking for a way to get the value of variable set in production while i'm running on test environment.
The config file :
development {
config.url = "http://local"
}
test {
config.url = "http://test.lan"
}
production {
config.url = "http://prod.lan"
}
The only way i know to get config variables is grailsApplication.config.url

The standard config setup only looks at the current environment. Holders has the same current config as grailsApplication. You have to slurp the config again. Try using ConfigurationHelper. A spock test is below. (Note the sometimes doubled config.config is because the first config is the property (or short name for getConfig() method) and your key contains the second config.)
import grails.test.mixin.TestMixin
import grails.test.mixin.support.GrailsUnitTestMixin
import spock.lang.Specification
import org.codehaus.groovy.grails.commons.cfg.ConfigurationHelper
#TestMixin(GrailsUnitTestMixin)
class ConfigSpec extends Specification {
void "test prod config"() {
def configSlurper = ConfigurationHelper.getConfigSlurper('production',null)
def configObject = configSlurper.parse(grailsApplication.classLoader.loadClass(grailsApplication.CONFIG_CLASS))
expect:
configObject.config.url == "http://prod.lan"
}
void "test dev config"() {
def configSlurper = ConfigurationHelper.getConfigSlurper('development',null)
def configObject = configSlurper.parse(grailsApplication.classLoader.loadClass(grailsApplication.CONFIG_CLASS))
expect:
configObject.config.url == "http://local"
}
void "test grailsApplication config"() {
expect:
grailsApplication.config.config.url == "http://test.lan"
}
void "test Holders config"() {
expect:
grails.util.Holders.config.config.url == "http://test.lan"
}
}

Check out Holders: https://gist.github.com/mathifonseca/ab443f1502bfd9461943
import grails.util.Holders
class FooService {
def foo() {
def devUrl = Holders.config.url
assert devUrl == "http://local"
}
}

Related

How to mock service in groovy/src class under test with Grails 3.3.x

I've recently upgraded to grails 3.3.1 and realised that grails.test.mixin.Mock has been pulled to separate project which has been build just for backward compatibility according to my understanding org.grails:grails-test-mixins:3.3.0.
I've been using #Mock annotation to mock Grails service injected into groovy/src class under test. What is the tactic to mock collaborating services in this case? Is there anything from Spock what I can use or should I fallback to grails-test-mixins plugin?
Class under test:
import gra
ils.util.Holders
import grails.util.Holders
class SomeUtilClass {
static MyService myService = Holders.grailsApplication.mainContext.getBean("myService")
static String myMethod() {
// here is some code
return myService.myServiceMethod()
}
}
My test spec (Grails 3.2.1):
import grails.test.mixin.Mock
import spock.lang.Specification
#Mock([MyService])
class ValidatorUtilsTest extends Specification {
def 'my test'() {
when:
def result = SomeUtilClass.myMethod()
then:
result == "result"
}
}
Due to you use Holders.grailsApplication in your SomeUtilClass, you can try to add #Integration annotation:
import grails.testing.mixin.integration.Integration
import spock.lang.Specification
#Integration
class ValidatorUtilsTest extends Specification {
def 'my test'() {
when:
def result = SomeUtilClass.myMethod()
then:
result == "result"
}
}
Not sure, but hope it work for you.
Try with this code
#TestMixin(GrailsUnitTestMixin)
#Mock([your domains here])
class ValidatorUtilsTest extends Specification {
static doWithSpring = {
myService(MyService)
}
def 'my test'() {
when:
def result = SomeUtilClass.myMethod()
then:
result == "result"
}
}
Remove the #Mock annotation and implement ServiceUnitTest<MyService> in your test class.

How do I import a Groovy class into a Jenkinfile?

How do I import a Groovy class within a Jenkinsfile? I've tried several approaches but none have worked.
This is the class I want to import:
Thing.groovy
class Thing {
void doStuff() { ... }
}
These are things that don't work:
Jenkinsfile-1
node {
load "./Thing.groovy"
def thing = new Thing()
}
Jenkinsfile-2
import Thing
node {
def thing = new Thing()
}
Jenkinsfile-3
node {
evaluate(new File("./Thing.groovy"))
def thing = new Thing()
}
You can return a new instance of the class via the load command and use the object to call "doStuff"
So, you would have this in "Thing.groovy"
class Thing {
def doStuff() { return "HI" }
}
return new Thing();
And you would have this in your dsl script:
node {
def thing = load 'Thing.groovy'
echo thing.doStuff()
}
Which should print "HI" to the console output.
Would this satisfy your requirements?

How to get the spring bean instance of a service, added via dependency injection in webflow

I would like to mock a service method in an integration test for one test, however I don't know how to get a reference to the service as it's added to the controller via dependency injection. To further complicate things the service is in a webflow, but I know it's not stored in the flow as the service is not serialized.
Ideal mocking scenario:
Get reference to the service
Mock the method via the metaClass
Main test
Set the metaClass to null so it's replaced with the original
Methods like mockFor so far don't seem to effect the service.
Example of the setup:
Controller:
package is.webflow.bad
import is.webflow.bad.service.FakeService
class FakeController
{
def index = {
redirect(action: 'fake')
}
def fakeFlow = {
start {
action {
flow.result = fakeService.fakeCall()
test()
}
on('test').to('study')
}
study {
on('done').to('done')
}
done {
System.out.println('done')
}
}
}
Service:
package is.webflow.bad.service
class FakeService
{
def fakeCall()
{
return 'failure'
}
}
Test:
package is.webflow.bad
import static org.junit.Assert.*
import grails.test.WebFlowTestCase
import is.webflow.bad.service.FakeService
import org.junit.*
class FakeControllerFlowIntegrationTests extends WebFlowTestCase
{
def controller = new FakeController()
def getFlow() { controller.fakeFlow }
String getFlowId() { "fake" }
#Before
void setUp() {
// Setup logic here
super.setUp()
}
#Test
void testBasic()
{
startFlow()
assertCurrentStateEquals 'study'
assertEquals 'failure', getFlowScope().result
}
#Test
void testServiceMetaClassChange()
{
// want to modify the metaClass here to return success
startFlow()
assertCurrentStateEquals 'study'
assertEquals 'success', getFlowScope().result
}
}
You can inject the service into your Integration test using "#AutoWired" or using application context you get reference. Am i missing something?
#Autowired
private YourService yourservice;
or
#Autowired
private ApplicationContext appContext;
YourService yourService = (YourService)appContext.getBean("yourService");
Here you go:
void "test something"() {
given: "Mocked service"
someController.someInjectedService = [someMethod: { args ->
// Mocked code
return "some data"
] as SomeService
when: "Controller code is tested"
// test condition
then: "mocked service method will be called"
// assert
}

Integration test - how to test a method with no inputs and a render

How does one integration-test (Grails) a controller with no inputs and a render view? Here is my controller code and test; the test looks correct but throws a "java.lang.Exception: No tests found matching grails test target pattern filter" error. many thanks for your help. -ryan
Controller code section:
class ReportSiteErrorsController {
static allowedMethods = [reportError: 'GET', saveReportError: 'POST']
def mailService
#Transactional(readOnly = true)
def reportError() {
render(view:'reportError', model:[])
}
}
Integration Test:
#TestFor(ReportSiteErrorsController)
class ReportSiteErrorsControllerTests extends DbunitGroovyTestCase {
#Test
void "test report error"() {
controller.reportError()
assert view == "reportError"
}
}
Leave the extension off in your command line. You are supposed to be specifying the name of the test, not the name of the file in which it is defined.
Use something like...
grails test-app integration: NameOfTest
Not something like...
grails test-app integration: NameOfTest.groovy
I hope that helps.
in Grails 2.4 the default syntax to test render "hello" would be:
import grails.test.mixin.TestFor
import spock.lang.Specification
/**
* See the API for {#link grails.test.mixin.web.ControllerUnitTestMixin} for usage instructions
*/
#TestFor(SimpleController)
class SimpleControllerSpec extends Specification {
def setup() {
}
def cleanup() {
}
void "test something"() {
controller.index()
expect:
response.text == "hello"
}
}
The assert won't do for me. See also: the Grails Documentation

Testing Service in Grails produces 'org.junit.ComparisonFailure: expected:<An[a]nymous> but was:<An[o]nymous>' error

I'm working my way through 'Grails in Action' and I'm running into an issue when trying to write an Integration test for one of my services.
I realize that I'm using Grails 2.0.3 whereas the book was written with Grails 1.x.x in mind.
Here is my Service:
package qotd
class QuoteService {
boolean transactional = true
def getRandomQuote(){
def allQuotes = Quote.list()
def randomQuote
if(allQuotes.size() > 0){
def randomIndex = new Random().nextInt(allQuotes.size())
randomQuote = allQuotes[randomIndex]
}
else{
randomQuote = getStaticQuote()
}
return randomQuote
}
def getStaticQuote(){
return new Quote(author: "Anonymous",
content: "Real Programmers Don't eat quiche")
}
}
And below is my Integration Test, located in '/test/integration/qotd/'
package qotd
import static org.junit.Assert.*
import org.junit.*
class QuoteServiceIntegrationTests extends GroovyTestCase {
def quoteService
#Before
void setUp() {
}
#After
void tearDown() {
}
#Test
void testStaticQuote() {
def staticQuote = quoteService.getStaticQuote()
assertNotNull quoteService
assertEquals "Ananymous",staticQuote.author
assertEquals "Real Programmers Don't Eat Quiche",staticQuote.content
}
}
Just in case it may be relevant, here is the Quote class that I'm testing the contents of above:
package qotd
class Quote {
String content
String author
Date created = new Date()
static constraints = {
author(blank:false)
content(maxSize:1000,blank:false)
}
}
When I run my test, using 'test-app -integration' I get the following:
Running 1 integration test... 1 of 1
Failure: testStaticQuote(qotd.QuoteServiceIntegrationTests)
org.junit.ComparisonFailure: expected: An[a]nymous but was:An[o]nymous
at org.junit.Assert.assertEquals(Assert.java:125)
at org.junit.Assert.assertEquals(Assert.java:147)
at qotd.QuoteServiceIntegrationTests.testStaticQuote(QuoteServiceIntegrationTests.groovy:24)
Any insight would be appreciated. Thank you all!
you spelled "Anonymous" incorrectly on this line
assertEquals "Ananymous",staticQuote.author

Resources