Service not injected for inline plugin tests in Grails - grails

My goal is to write test for my own Grails plugin. steps taken so far:
Step - Create separate grails app (in our case, testApp) inside
the Grails Plugin 'test' folder
Step - Make the plugin to be
inline for the application - testApp by adding following Line in BuildConfig.groovy
grails.plugin.location.PluginName = '../../../../PluginName'
The issue is that in the Unit test, the Service (from the inline plugin) are not injected like it is for regular app in Unit Test. Here is sample test:
#TestFor(SampleService)
class SampleServiceUnitSpec extends UnitSpec {
def "Sample Test"(){
setup:
def test = 'ok'
when:
test = "changed"
then:
assert service
assert "changed" == test
}
}
The service is injected if this test is run from grails app and service is part of the app. The service is not injected if this test is run from the testApp with inline plugin containing the service. The service is not injected if the test is plugin unit test and the service declared in the plugin.
How to inject service so it can be tested? Any good docs,posts.etc on how best test Grails plugins? Thank You

Why you want to create a unit test for your plugin service inside an application. Shouldn't be better your application just worry with his own code?
I suggest you to separate your concerns: plugin classes should be tested in the plugin, and application classes in the application. For the point of view fo the application, assume that your services "should just work", because they are well tested in the plugin.
Also, I advise against creating an application inside your Grails plugin. The test folder is used only for your test classes and nothing more.
If you want to maintain only the last version of your plugin, you can create just one application (in another folder, outside your plugin) and always update there.
If you need to maintain more than one version, or more than one Grails version, then maybe a Groovy script that create your test application with an specified version will be a better approach.

Related

Cucumber-jvm #after with Appium driver

I'm using cucumber-jvm , and trying to implement global #After method which should be executed only once after all scenario's execution was completed.
The #After method should quit the appium driver.
Currently #After hook being executed after each running scenario , and it means that the driver should be created each time from scratch , but I do want to reuse it.
Any help will be much appreciated
You can try using QAF which support Gherkin, where driver management is taken care by the framework. It is dedicated framework built upon TestNG for web, mobile web, mobile native, and webservices functional test automation.
When using QAF you don't need to write any code to setup/teardown driver. You can configure as per your need through testng xml configuration file and properties. You can specify behavior by using property selenium.singletone. For example:
#will reuse driver session for close browser after all testcase configured under xml test node
selenium.singletone=true
#will teardown after each scenario/testcase
selenium.singletone=Method
#will reuse driver session for group
selenium.singletone=Groups
If you are running in parrallel it will you can have driver session sharing between test running in same thread. All combinations you can achieve through execution configuration.
Moreover, you can use all TestNG listener and annotations. For example:
#BeforeMethod:Invokes Before each Testcase/Scenario
#BeforeSuite: Invokes once before entire suite
#BeforeTest: Invokes once before each xml test node for each xml test node in configuration
#BeforeGroup: Invokes once before starting execution of test in group for each group
#AfterSuite: Invokes once after entire suite
#AfterTest: Invokes once after entire xml test node
#AfterGroup:Invokes once after all test in group for each group
#AfterMethod:Invokes after each Testcase/Scenario
Refer Gherkin with QAF

Where do I put test resources in Grails (2.4)?

I'm working on a service class that needs to process some sort of data payload. In my automated tests, I'm adding some mock data to check the behavior of the service for different inputs. I need to extract these mock data to several files so I can reuse them for other tests. Where do I put such file in a Grails (2.4) app? By convention, most Java projects have src/test/resources for the purpose, but Grails doesn't seem to consider that.
If you are writing unit tests you can put them under test/unit/resources and if you are writing integration tests you put them under test/integration/resources.

How to run GrailsPlugin.groovy during 'war'

Grails Version: 2.3.11
Dear all,
I have a plugin where in the doWithSpring Closure I use some central resources to build up a properties file in the war that is then used during runtime. The central resources will only be available when building the war in a production environment so putting the files into the /src (for example) of the plugin is out of the question.
Currently my plugin will work in a run-app and testing environment, but the file is never created when 'war' is run.
I have tried setting the scopes variable to include war but this doesn't appear to be doing much (or at least, is not invoking the doWithSpring closure). Does anyone know how to do this or if it is possible?
All of the logic is within doWithSpring (which delegates to a class) but that is only using the classLoader and grailsApplication so if there is anywhere else I can do this that will also be great.
Thanks
Adam
Okay, the best approach is to hook into the events with your plugin. I highly recommend you read the documentation on events. It's as simple as creating the correct file within your plugin and placing your code within the associated closure.
For example:
scripts/_Events.groovy
eventCreateWarStart = { warName, stagingDir ->
// place your code here.
}

Creating general purpose gant scripts

Is it possible to create gant scripts to automate generalized processes.
e.g. Grails provides a default script 'create-app' to create a project using a tomcat container. Now suppose that I want to write my own script that could create projects using jboss as a server. I would like to save this script in a generalized manner so that I can use it to create more projects, rather than save it under some specific projet.
Is it possible to do that?
Yes, save it in $HOME/.grails/scripts. This way it will be available to all Grails installs.
Note that the naming convention is important; if the script starts with an underscore, it cannot be called directly as a script, only included in others (e.g. to store common code and methods). If it ends in an underscore, it can be called outside of a project (e.g. the create-app script is named CreateApp_.groovy). If there's no leading or trailing underscore then it can be called from within a project.

How can I access a file in my Grails plugin from a src file in the same plugin?

I'm working on a JavaScript testing plugin for Grails. I wrote some Groovy classes to perform the testing that I've stored in my src/groovy folder. I hook into the testing events in my plugin's _Events.groovy script and inject an instance of the test runner. From that instance of the test runner, I need to access the JavaScript files, which I've stored in src/js, to perform the testing.
The plugin documentation specifies a way to get the path from my Gant scripts, but that doesn't work elsewhere. I've also tried to get access to the GrailsApplication via grailsApplication or ApplicationHolder, but I get null. Finally, I've tried accessing BuildSettings and ConfigurationHolder, but those show me an empty configuration.
To make my plugin work, I am currently copying the JavaScript files into the application's test/resources folder so it's in a known location relative to the working directory, which I'm assuming is the project folder. This feels invasive and fragile to me, so I'd like to figure out a "right" way.
How can I get a path to my plugin from my test runner so I can find those files?
If you have the BuildSettings and the pluginManager bean (either dependency-injected with def pluginManager or via PluginManagerHolder) then you can get the path with
new File(buildSettings.projectPluginsDir, pluginManager.getPluginPath('foo'))

Resources