Using EasyB in Grails - grails

It's probably going to be one of the lame and novice level questions but I'm struggling with it for some time and it's still not working.
I have a HomeController:
package example
class HomeController {
def index = {
[ message: "Hello, world!" ]
}
}
Now I've installed easyb plugin:
grails install-plugin easyb
I've also created a basic story for this controller (in "test/unit" folder):
scenario "Should return 'Hello, world!' message", {
given "Controller is instantiated", {
mockController HomeController
controller = new HomeController()
}
when "Controller received request for index action"
and "No additional parameters are expected", {
result = controller.index()
}
then "Controller displays Hello, world!", {
result.message.shouldBe "Hello, world!"
}
}
When I run the easyb tests
grails test-app unit:easyb
instead of this test passing as it should I get the following error message at "when No additional parameters are expected":
[FAILURE: No signature of method: HomeController.index() is applicable for argument types: () values: []]
and then for the second part at "then Controller displays Hello, world!"
[FAILURE: No such property: result for class: HomeController]
I'm basically following the instructions from http://grails.org/plugin/easyb.
Can anyone explain to me what I'm doing wrong?
Matthias.

Oh well, I found it... conventions, conventions, conventions....
Naming the scenario file HomeController.story forced the engine to include "controller" variable in the scope. What's not clear though is why I couldn't do it again...
Nevermind. After removing the "given" part completely it works as it should.

Related

How to print out spock metadata(the conent of given|when|then) when specs running?

Is it possible or not?If yes,it will be a big help for debugging.
Update:
For metadata,I mean the content of after given|when|then statement,such as:
def "test case"...
given:"some preconditions"
when:"do something"
then:"some result"
...
I want that blow content got printed:
"test case" begins
"some preconditions"
"do something"
"some result"
Currently this is not possible because even if you write a Spock extension, the deepest you can hook into at the moment is feature method execution. I.e. what you could do is print all block labels before or after a method is executed, but not interspersed with your own log output during method execution. There is no hook or interception point for intra-method block execution at the moment.
See also these feature requests (still unanswered, unfortunately):
https://github.com/spockframework/spock/issues/538
https://github.com/spockframework/spock/issues/645
What is also possible around logging block labels is to write HTML test reports as a test documentation. But this is a reporting thing and not something you can use during a running test.
Update: Meanwhile a little workaround. Put this in your global Spock config script (usually src/test/resources/SpockConfig.groovy:
import spock.lang.Specification
class LabelPrinter {
def _(def message) {
println message
true
}
}
Specification.mixin LabelPrinter
Then use it from Spock or Geb tests like this (please note the underscores after the labels):
package de.scrum_master.testing
import spock.lang.Specification
class MySpockTest extends Specification {
def "interaction"() {
given:_ "My given comment"
def foo = 11
def bar = foo + 4
println "blah"
expect:_ "My expect comment"
interaction {
foo = 2
bar = 5
true
}
println "foo"
foo * bar == 10
foo + bar == 7
and:_ "My and comment"
true
}
}
Console log:
My given comment
blah
My expect comment
foo
My and comment

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: use Spock to test template rendering

I use Spock to test an action of a controller as below:
code in controller:
def milestoneChange() {
Milestones selectedMilestone = dataQueryService.getMilestone(params.id)
Tasks[] tasksList = dataQueryService.getTasksList(params.id)
List enumerateNameList = dataQueryService.getEnumerateNameList()
render(template: 'milestoneSummary', model: [selectedMilestone: selectedMilestone, tasksList: tasksList, enumerateNameList: enumerateNameList, selectedMilestoneID: params.id])
}
code in test:
#TestFor(MilestonesMgtController)
class MilestonesMgtControllerSpec extends Specification {
void "change the milestone"() {
when:
views['/milestonesMgt/_milestoneSummary.gsp'] = "test"
controller.params.id = 'Late Stage Review'
controller.milestoneChange()
then:
controller.response.text == 'test'
}
}
Because the content of the _milestoneSummary.gsp is very long, I use the approach mentioned in both Grails documentation and http://www.javacodegeeks.com/2013/09/grails-goodness-unit-testing-render-templates-from-controller.html which is using views['/milestonesMgt/_milestoneSummary.gsp'] to mock the template. However, the response is still the original long content? Does anyone know what is wrong with my code? Thanks very much!!!
BTW when using params/response/model, I have to use controller.xxx, but I see the sample code in documentation use params/response/model directly, do you know why?
I am using Grails 2.3.8
the project link http://github.com/jackyying1130/MMS
the test is located in MMS/test/integration/phdmilestonemanagementsystem/MilestonesMgtControllerSpec.gr‌​oovy

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 2.3.8 isn't working with external configuration

I'm running a test with Grails 2.3.8 and an external configuration, yet the value doesn't seem to be coming through. I've tried this in older versions and am not seeing the same error. Did something change or am I missing something that I fat fingered? I am using an absolute path and the file definitely exists because Grails sees the key.
Config.groovy
reliable.string = "This string is working"
grails.config.locations = ["file:/home/howes/Project/project/test-config.groovy"]
/home/howes/Project/project/test-config.groovy
test.externalstring = "this is a test"
To test it I made a controller and just called grailsApplication to pull out the values. The first time I load the page I get a blank map, and when I refresh I see the key but no value. To make sure I am pulling everything correctly I am outputting the test-config.groovy item and one from the basic Config.groovy.
TestContoller.groovy
class TestController {
def grailsApplication
def index() {
println grailsApplication.config.test
println grailsApplication.config.reliable
return [ext:grailsApplication.config.test.externalstring, ext2:grailsApplication.config.reliable.string]
}
}
Console Output (First Load)
[:]
[string:This string is working]
Console Output (Page Refresh)
[externalstring:[:]]
[string:This string is working]
What am I missing here?

Resources