I have created properties at project, testsuite and test case level.
At test case level, I created a groovy script with
String[] props = context.getPropertyNames()
for (prop in props) {
log.info prop
}
It executes but output in log window is weird :
INFO:RunCount
INFO:log
INFO:Thread Index
Why I can't see the properties I created ?
You can get the properties(from groovy script) defined at
Test Case level:
def testCaseProperties = testRunner.testCase.properties
log.info "Test Case Properties :\n$testCaseProperties"
If you want value of certain property
log.info testCaseProperties.getPropertyValue('PROPERTY_NAME')
Or
log.info context.expand('${#TestCase#PROPERTY_NAME}')
Test Suite Level:
def testSuiteProperties = testRunner.testCase.testSuite.properties
log.info "Test Suite Properties :\n$testSuiteProperties"
Project Level:
def projectProperties = testRunner.testCase.testSuite.project.properties
log.info "Project Properties :\n$projectProperties"
Similarly you may use context to get certain property value available at different level by
context.expand('${#TestSuite#PROPERTY_NAME_OF_SUITE}')
context.expand('${#Project#PROPERTY_NAME_OF_PROJECT}')
for suite, project respectively
Related
Can someone tell me what the controller object in controller.searchService, controller.search() and controller.response.text.contains refers to? How is this controller object created and what is its purpose?
import grails.test.mixin.TestFor
import spock.lang.Specification
#TestFor(BookController)
#Mock(Book)
class BookControllerSpec extends Specification {
void "test search"() {
given:
def searchMock = mockFor(SearchService)
searchMock.demand.searchWeb { String q -> ['first result', 'second result'] }
searchMock.demand.static.logResults { List results -> }
controller.searchService = searchMock.createMock()
when:
controller.search()
then:
controller.response.text.contains "Found 2 results"
}
}
controller is an instance of your Controller under test, specified in the #TestFor annotation. In this case, it is the BookController. It's created by Grails for you to use in your unit tests.
controller.searchService is the BookController's reference to the SearchService bean, which you mock in the given block.
controller.search() is calling the BookController's search action.
controller.response.text is the text output that the action writes to the response.
The Testing docs are for the newest, Trait-based, version of the testing framework but the concepts are still the same.
I've two test case A and B under one test suite
I am setting the context property in script assertion of one of the test step of B
def holder = new XmlHolder( messageExchange.responseContentAsXml )
context.setProperty("xmlHolder", holder)
I am getting the context property in script assertion of one of the test step of A
def Holder=context.getProperty("xmlHolder")
log.info(Holder)
but the value of "Holder" is printed null
I just want to set it in one TC and get it in the other one.
EDIT
Found this , and I was trying to set property like this. I already had a Runner created in script assertion.
Runner.getTestCase().setPropertyValue("xmlHolder", holder)
But receiving a null error
I could do
Runner.getTestCase().setPropertyValue("xmlHolder", "A")
Just wondering , if TC properties can hold an Object compare to string. So, my original question remains as it is.
Based on above comments, got this working
setting property in script assertion of B
context.testCase.testSuite.setPropertyValue('xmlHolder', messageExchange.responseContentAsXml)
getting property in script assertion of B and converting it to XmlHolder object
def HolderContent=context.testCase.testSuite.getPropertyValue('xmlHolder')
def Holder = new XmlHolder ( HolderContent)
I'm trying to utilize the build-test-data plugin in my Grails (v2.4.3) app to assist with test data creation for unit testing, but while running my unit tests the plugin cannot find TestDataConfig.groovy to load my specified values (for unique constraint tests, etc).
I've installed the plugin via including it in BuildConfig.groovy:
plugins {
...
test ":build-test-data:2.2.0"
...
}
I've ran the following command to create the TestDataConfig.groovy template, which places the file at \grails-app\conf\:
grails install-build-test-data-config-template
I've followed the general instructions on the plugin wiki to come up with a properly formatted file:
testDataConfig {
sampleData {
'<path>.User' {
def a = 1
username = { -> "username${a++}" }
}
}
}
(Where path is the fully-qualified class name.)
In my tests, I am using the following general format:
import grails.buildtestdata.TestDataConfigurationHolder
import grails.buildtestdata.mixin.Build
import grails.test.mixin.TestFor
import spock.lang.Specification
import spock.lang.Unroll
#TestFor(User)
#Build(User)
class UserSpec extends Specification {
def setup() {
mockForConstraintsTests(User)
TestDataConfigurationHolder.reset()
user = User.buildWithoutSave()
}
#Unroll
void "test #field must be unique"() {
given: 'a User exists'
user.save(flush: true)
when: 'another User is created with a non-unique field value'
def nonUniqueUser = User.buildWithoutSave()
nonUniqueUser."$field" = user."$field"
then: 'validation fails and the field has a unique constraint error'
!nonUniqueUser.validate()
nonUniqueUser.errors.errorCount == 1
nonUniqueUser.errors.getFieldError("$field").code == 'unique'
where:
field << ['username', '<some other field>']
}
}
But, when the test is run (using IntelliJ IDEA) TestDataConfig.groovy cannot be found via the following method in the plugin:
static Class getDefaultTestDataConfigClass() {
GroovyClassLoader classLoader = new GroovyClassLoader(TestDataConfigurationHolder.classLoader)
String testDataConfig = Holders.config?.grails?.buildtestdata?.testDataConfig ?: 'TestDataConfig'
try {
return classLoader.loadClass(testDataConfig)
} catch (ClassNotFoundException ignored) {
log.warn "${testDataConfig}.groovy not found, build-test-data plugin proceeding without config file"
return null
}
}
So the test continues on without a config file and I do not get uniquely generated data sets.
I've even tried explicitly including the file in Config.groovy:
grails.buildtestdata.testDataConfig = "TestDataConfig"
But, the same method in the plugin shows that Holders.config? is null.
I've looked at a few solutions to a similar problem here on StackOverflow with nothing working in my case; I cannot figure out how to get my app to detect the presence of the TestDataConfig.groovy file.
Any ideas? Thanks so much!
I've an app based on Grails 1.3.7. And I need to write a unit test for a custom taglib that is based on the built-in taglib, <g:select /> to be specific.
I checked out the solution on this previous SO post but the solution stated is not working in my case (some properties are not being prooperly mocked up).
The other solution that I found was this. Using this approach, I get most of the properties of FormTagLib mocked up except for the grailsApplication property that select requires. The actual error that I get is Cannot invoke method getArtefact() on null object.
How can I properly write the unit test in such a case?
Edit
Here are my test class and the full stacktrace. Line #45 on the stacktrace is the call to the g.select from my custom taglib. My custom taglib is something like
def clientSpecificQueues = {attrs->
def queueList = taskService.getClientSpecificQueues(session.clientName)
def queueLabel = "Some String"
if (queueList.size() > 0){
out << queueLabel
else
out << g.select(name:'queueId', from: queueList, optionKey: 'id', optionValue: 'name')
}
I believe grailsApplication will never be mocked by default, it has too many responsibilities. I'd try to brutally patrially mock grailsApplication in setUp() by doing something like
tagLib.grailsApplication = [getArtefact: { -> return something suitable }]
Is it possible to directly set a System.property for a particular method of a Grails unit test class?
I've got a Filters class that blocks some actions if a system property is set in Config.groovy:
class MyFilters {
def filters =
{
if ('true'.equals(System.properties.getProperty('myProperty', 'false'))){
writeFilter(controller: "myController", action: "update")
{
before =
{
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return false;
In MyControllerTests, I'm trying to implement a test for the filter:
void testMyFilter(){
System.properties.setProperty('myProperty', 'true')
withFilters(action:"update") {
controller.update()
}
assert response.status == HttpServletResponse.SC_FORBIDDEN
}
But the filter class is already mocked at this stage (using the default 'false' property value from Config) so the change of the property in the test has no effect.
Is there a way around this, or a way to force Grails to reload the Filters class after the prop is changed? I can't change the default property in Config as the other controller tests will break, it's just for a particular environment where this prop will be set so I'd like the scenario covered by a test that checks the Filter will kick in.
Thanks.
Inevitably, I found out how to do it about a minute after I posted this. Adding mockFilters(MyFilters) after the setProperty makes Grails rebuild the mocked filter with the updated property.