Error testing spock mandril grails v2.4.3 - grails

I'm testing a Grails application but i get this error message:
I'm trying to do unit test. My Grails version is 2.4.3
Error executing script TestApp: java.lang.ClassNotFoundException: grails.plugin.spock.
That's my code:
#TestFor(TrackEmailController)
#Mock(TrackEmail)
class TrackEmailUnit2Spec extends Specification {
def setup() {
}
def cleanup() {
}
void "test something"() {
}
void 'test mandrillEventsEndPoint'() {
when:
controller.mandrillEventsEndPoint()
then:
response.text == 'mandrill Events End Point'
}
}

Can you be a little more specific on how you are running your test cases and how you have integrated spock dependencies? Or perhaps provide a github link to replicate the issue?

Related

Spock 'throw new Exception()' feature not working

I am trying to make use of {throw new Exception()} in Spock, but on running the test it prints in report--
"The following problems occurred:
Expected exception of type 'java.lang.Exception', but no exception was thrown"
package testing
import spock.lang.Specification
class MyFirstSpec extends Specification {
def "Test_One" (){
given:
def obj = new SpockMethodsPlaceholder()
obj.returnAge(0) >> {throw new Exception("invalidAge")}
when:
1*obj.returnAge(0)
then:
Exception ex = thrown()
ex.getMessage() == "invalidAge"
}
class SpockMethodsPlaceholder {
def "returnAge" (int age){
return age
}
}
}
Is there something wrong with my code?
Below is the stack trace of test run---
Working Directory:
Gradle User Home: /home/mafia/.gradle
Gradle Distribution: Gradle wrapper from target build
Gradle Version: 4.3
Java Home: /usr/lib/jvm/java-8-oracle
JVM Arguments: None
Program Arguments: None
Build Scans Enabled: false
Offline Mode Enabled: false
Tests: testing.MyFirstSpec
:compileJava UP-TO-DATE
:compileGroovy NO-SOURCE
:processResources NO-SOURCE
:classes UP-TO-DATE
:compileTestJava
:compileTestGroovy
:processTestResources NO-SOURCE
:testClasses
:test
testing.MyFirstSpec > Test_One FAILED
org.spockframework.runtime.WrongExceptionThrownError at MyFirstSpec.groovy:16
1 test completed, 1 failed
There were failing tests. See the report at: file:///media/mafia/A08200E98200C62E/Study/Git_Repo/GIT_JAVA/workbench/SpockProject/build/reports/tests/test/index.html
BUILD SUCCESSFUL in 19s
4 actionable tasks: 3 executed, 1 up-to-date
It looks like you misunderstand the concept of stubbing/mocking
What exactly is tested? Class SpockMethodPlaceholder? In this case it should not be mocked/ stubbed its a "class-under-test" - the code that you check and want to gain a confidence that it works (the code in the methods of this class if you wish)
On the other hand, if you use >> syntax you probably do intend to Stub something.
So here is a better example:
public class SomeClass {
public int return getAge(int age) {
if(age <= 0) {
throw new IllegalArgumentException("too young");
} else {
return age;
}
}
}
class SomeClassTest extends Specification {
def "an exception is thrown if the person is too young" () {
given:
def subject = new SomeClass()
when:
subject.getAge(-1)
then:
def ex = thrown(IllegalArgumentException)
ex.message == "too young"
}
}

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

Grails Fixtures / Build Test Data plugin not working within a Unit Test

I am trying to use the Grails Fixtures Plugin within a service unit test. I am using grails 2.2.
I have the next code in my BuildConfig.groovy
plugins {
compile ":fixtures:1.2"
compile ":build-test-data:2.0.3"
...
..
.
}
Initially I tried
#TestFor(HotelService)
#Mock([Place])
class HotelServiceTests {
def fixtureLoader
void testFixturesInUnitTests() {
def fixture = fixtureLoader.build {
hotel(Place, name: "Hotel Hilton")
}
}
}
The above test was failing:
| java.lang.NullPointerException: Cannot invoke method build() on null object
With a Google Search I found in the Grails User Mailing List that the fixtureLoader have to createdexplicitly inside the unit test.
import grails.plugin.fixtures.*
#TestFor(HotelService)
#Mock([Place])
class HotelServiceTests {
def fixtureLoader
def grailsApplication
#Before
void setUp() {
fixtureLoader = new FixtureLoader(grailsApplication)
}
void testFixturesInUnitTests() {
def fixture = fixtureLoader.build {
hotel(Place, name: "Hotel Hilton")
}
}
}
Test failed with the next error:
java.lang.NullPointerException: Cannot invoke method hasGrailsPlugin() on null object
at grails.plugin.fixtures.builder.FixtureBuilder.lookForBuildTestDataPlugin(FixtureBuilder.groovy:53)
at grails.plugin.fixtures.builder.FixtureBuilder.<init>(FixtureBuilder.groovy:49)
at grails.plugin.fixtures.Fixture.createBuilder(Fixture.groovy:75)
at grails.plugin.fixtures.Fixture.build(Fixture.groovy:44)
at grails.plugin.fixtures.FixtureLoader.build(FixtureLoader.groovy:46)
Another GoogleSearch and I found a 'hack' to avoid the previous error.
import grails.plugin.fixtures.*
import org.codehaus.groovy.grails.plugins.GrailsPluginManager
import org.codehaus.groovy.grails.plugins.PluginManagerHolder
#TestFor(HotelService)
#Mock([Place])
class HotelServiceTests {
def fixtureLoader
def grailsApplication
#Before
void setUp() {
fixtureLoader = new FixtureLoader(grailsApplication)
PluginManagerHolder.pluginManager = [hasGrailsPlugin: { String name -> true }] as GrailsPluginManager
}
void testFixturesInUnitTests() {
def fixture = fixtureLoader.build {
hotel(Place, name: "Hotel Hilton")
}
}
}
Now I am getting the next error:
java.lang.NullPointerException: Cannot invoke method isDomainClass() on null object
at grails.plugin.fixtures.buildtestdata.BuildTestDataBeanDefinitionTranslator.translate(BuildTestDataBeanDefinitionTranslator.groovy:54)
at grails.plugin.fixtures.buildtestdata.BuildTestDataBeanDefinitionTranslator.translate(BuildTestDataBeanDefinitionTranslator.groovy:43)
at grails.plugin.fixtures.builder.FixtureBuilder.translateToBuild(FixtureBuilder.groovy:126)
at grails.plugin.fixtures.builder.FixtureBuilder.invokeMethod(FixtureBuilder.groovy:121)
at com.softamo.movilrural.TopRuralScraperServiceTests$_testFixturesInUnitTests_closure2.doCall(TopRuralScraperServiceTests.groovy:26)
I have no idea how to solve this. Any feedback is really welcome.
The fixtureLoader.build() method integrates with the Build Test Data plugin. The fixtures plugin is intended to be used in conjunction with integration tests.
See also this issue http://jira.grails.org/browse/GPFIXTURES-21.
The #TestFor annotation marks test as unit, so you need to remove it.
File /test/integration/com.example/HotelServiceTests.groovy
class HotelServiceTests extends GroovyTestCase {
FixtureLoader fixtureLoader
Fixture fixture
void setUp() {
fixture = fixtureLoader.load {
build {
hotel(Place, name: "Hotel Hilton")
}
}
}
void testFixturesInUnitTests() {
// given:
HotelService service = new HotelService()
// when:
List<Place> hotels = service.list()
// then:
assert hotels.size() == 1
assert hotels[0] == fixture.hotel
}
}
Hope it helps you.
I'm not really an expert on fixture loader, but it seems you're just calling the wrong method (build instead of load).
#TestFor(HotelService)
#Mock([Place])
class HotelServiceTests {
def fixtureLoader
void testFixturesInUnitTests() {
def fixture = fixtureLoader.load {
hotel(Place, name: "Hotel Hilton")
}
}
}
I haven't tried it, but you can look at the fixtures loader usage here: Grails Fixtures Plugin - Reference Documentation
There is not really a way to support the use of fixtures plugin in a Grails Unit test.
You can achieve the same goals by using BuildTestData plugin, which provides the #Build annotation which supports the UnitTests.

Grails: testing a redirect with an integration test

I'm using Grails 1.3.7. I'm trying to test a redirect in my integration test. Here is my controller and method in question ...
class HomeController {
def design = {
....
if (params.page) {
redirect(uri: "/#/design/${params.page}")
}
else {
redirect(uri: "/#/design")
}
break;
}
}
However in my integration test, the call to "controller.response.redirectedUrl" is failing (always returns null) even though I know the redirect call is being made (verified through logging). What is wrong with the integration test below?
class HomeControllerTests extends grails.test.ControllerUnitTestCase {
....
void testHomePageDesign() {
def controller = new HomeController()
// Call action without any parameters
controller.design()
assert controller.response.redirectedUrl != null
assertTrue( responseStr != "" )
}
Thanks, - Dave
Changing your HomeControllerTests to extend GrailsUnitTestCase should fix the problem.
class HomeControllerTests extends grails.test.GrailsUnitTestCase {
....
}
The various ways of generating a test class all seem to vary the class that is extended.
create-integration-test => GroovyTestCase
create-unit-test => GrailsUnitTestCase
create-controller => ControllerUnitTestCase
However, according to the Test section of the Grails User Guide, GrailsUnitTestCase is the core part of the testing frame and, at least in 1.3.7, that is the best class to base test classes on.

How to use a custom codec in a Grails unit test

I am working through a Grails tutorial from InfoQ called Getting Started With Grails, Second Edition, and I am trying to add a custom codec to a unit test. My environment is Grails 1.3.7 and Groovy 1.7.8.
So the codec is SHACodec.groovy, and it lives in grails-app/utils. The contents are:
import java.security.MessageDigest
class SHACodec{
static encode = {target->
MessageDigest md = MessageDigest.getInstance('SHA')
md.update(target.getBytes('UTF-8'))
return new String(md.digest()).encodeAsBase64()
}
}
The codec works just fine when I log into the app. It's being used for a password field in my UserController.authenticate()
def authenticate = {
def user =
User.findByLoginAndPassword(params.login, params.password.encodeAsSHA())
if(user){
session.user = user
flash.message = "Hello ${user.login}!"
redirect(controller:"race", action:"list")
}else{
flash.message = "Sorry, ${params.login}. Please try again."
redirect(action:"login")
}
}
When I add this to a unit test, the following error displays:
No such property: SHACodec for class:
racetrack.UserControllerTests
groovy.lang.MissingPropertyException:
No such property: SHACodec for class:
racetrack.UserControllerTests at
racetrack.UserControllerTests.testAuthenticate(UserControllerTests.groovy:39)
The test is:
package racetrack
import org.codehaus.groovy.grails.plugins.codecs.*
import grails.test.*
class UserControllerTests extends ControllerUnitTestCase {
protected void setUp() {
super.setUp()
String.metaClass.encodeAsSHA = {->
SHACodec.encode(delegate)
}
}
protected void tearDown() {
super.tearDown()
}
void testAuthenticate(){
def jdoe = new User(login:"jdoe", password:"password".encodeAsSHA())
mockDomain(User, [jdoe])
controller.params.login = "jdoe"
controller.params.password = "password"
controller.authenticate()
assertNotNull controller.session.user
assertEquals "jdoe", controller.session.user.login
controller.params.password = "foo"
controller.authenticate()
assertTrue controller.flash.message.startsWith(
"Sorry, jdoe")
}
I found two different recommendations so far.
First, call the codec directly from the test:
SHACodec codec = new SHACodec()
codec.encode("password")
Second, use an integration test instead of a unit test.
The results were the same for each option. What is the small thing I am missing?
Thanks in advance for your time!
you are not importing your codec--you are importing the default grails codecs. You just need to make the import for the codec in the test match the exact package path of where the codec lives. If you are using an IDE, let it try to import the codec for you...
Use the loadCodec method of the GrailsUnitTestCase. It's very simple. See the example bellow:
import grails.test.*
import org.codehaus.groovy.grails.plugins.codecs.HTMLCodec
class SomeTests extends GrailsUnitTestCase {
protected void setUp() {
super.setUp()
loadCodec(HTMLCodec)
}
protected void tearDown() {
super.tearDown()
}
void testSomething() {
assertEquals "<p>Hello World</p>", "<p>Hello World</p>".encodeAsHTML()
}
}
The answer from #hvgotcodes is correct, but you also need to add the grails-app/utils folder to your Java Build Path before the import works (at least that's what I needed to do with SpringSource Eclipse IDE).

Resources