In my Integration test, I have #Shared fields that are loaded from fixtures(Fixtures plugin for grails). Those fields are aliases for the fixture beans. Look at the code I have now!
#TestFor(OrganizationUserService)
class OrganizationUserServiceSpec extends Specification {
def fixtureLoader
#Shared
def fixture
#Shared
def activeOrganizationOne
#Shared
def activeChild1
def setup() {
fixture = fixtureLoader.load {
build {
activeOrganizationOne(Organization) {
name = "Active Organization"
active = true
parent = null
}
activeChild1(Organization) {
name = "Active Child One"
active = true
parent = activeOrganizationOne
}
}
activeOrganizationOne = fixture.activeOrganizationOne
activeChild1 = fixture.activeChild1
}
void "deactivateOrganization deactivates an organization and all its children"() {
given:
service.organizationService = new OrganizationService()
service.userService = new UserService()
when:
service.deactivateOrganization(activeOrganizationOne)
//the above method deactivates activeOrganizationOne and activeChild1
//and activeChild1 will have a disableReason = PARENT_DEACTIVATION
then:
!activeOrganizationOne.active
!activeChild1.active
DisableReason.PARENT_DEACTIVATION.toString() == activeChild1.disableReason.toString()
}
}
Surprising it is for me that it works. activeChild1 is found by the service method via GORM request. How is it then the #Shared object in the test class modified?
To explain more, deactivateOrganization gets the childs of the organization using Organization.findAllByParent(org). In which org is the parameter passed to deactivateOrganization. if deactivateOrganization only modifies the objects that are returned from the GORM call, then how does #shared fields in the test catch the change? I didn't refresh anything.
I am on Grails 2.3.11 and running with mongoDB.
I am trying to create a standard on how to right Integration tests. So, I want to know the right way to work with fixtures and Integration tests.
Thanks In Advance;
Related
There is a main class named 'MainProcess.scala' that I'm running some test cases for it. I wanno write an end to end test for this class to validate it's functionality.
Th problem here is the end to end test requires some criteria has to be established to be able to test whole functionality. For instance:
class MainProcess() {
def foo(someparams):Future[Boolean] = {
if criteria true else false
}
def bee(some params):Future[WSResponse] = {
// call a micro service
}
}
My question is: Is it a good practice to mock 'foo' method such that it always return true or mock 'bee' method so that test can pass through these modules and continue till it reaches the point I intend to see it's result. As I am testing this class, I know that mocking the same class results into error or malfunctionality of test case:
private def guiceApplicationBuilder(app: Application): Application = {
new GuiceApplicationBuilder()
.overrides(bind[MainProcess].toInstance(mainProcessMock))
.build()
}
If this is not a good practice, so how to do such stuff to mock specific modules of main class?
Thank you in advance.
In Cucumber, how do i go about passing variables between step definition classes. Im trying to implement in Scala.
Looking around I have seen people suggest using Guice or Picocontainer or any other DI framework. But have not really come across an example in Scala.
For instance for the example below how do I pass the variable using DI ?
Provider.scala,
class Provider extends ScalaDsl with EN with Matchers with WebBrowser {
......
When("""I click the Done button$""") {
val doneButton = getElement(By.id(providerConnectionButton))
doneButton.click()
}
Then("""a new object should be created successfully""") {
// Pass the provider ID created in this step to Consumer definition
}
}
Consumer.scala,
class Consumer extends ScalaDsl with EN with Matchers with WebBrowser {
......
When("""^I navigate to Consumer page$""") { () =>
// providerId is the id from Provider above
webDriver.navigate().to(s"${configureUrl}${providerId}")
}
}
You can use ThreadLocal to solve your problem
Here's code snippet for solution.
object IDProvider{
val providerId = new ThreadLocal[String]
def getProviderId: String = {
providerId.get()
}
def setProviderId(providerId: String): Unit = {
providerId.set(providerId)
}
}
To access providerID across different step definitions. You can simply call IDProvider.getProviderId
And to set the value of providerID, simply call IDProvider.setProviderId(PROVIDER_ID)
I have a requirement in my grails app to connect to an existing mongodb server. I am using the plugin ':mongodb:3.0.3' to do this. I have a domain class that is basically empty
class Thing {
static mapWith = "mongo"
String id
String name
static constraints = { }
static mapping = {
collection "myThing"
id column: '_id', generator: 'assigned'
version false
}
}
And I am trying to save a new domain object in an integration test -- a precursor to a controller action:
def "create the thing"() {
def thing = new Thing(name: "name", id:"foobar")
when:
def foo = thing.save(flush: true, failOnError:true)
then:
Thing.findByName("name")
}
The test fails because Thing.findByName returns null, however, when I dig into the low level API, I can save an object. The following test passes:
def "create the thing low level"() {
when:
Thing.collection.insert([name:"name"])
then:
Thing.findByName("name")
}
I have looked at the other stackoverflow questions and they seem to deal with:
Not using flush, which I am
Not having the configuration setup propertly, which I do because I have been fetching records from it, and the low level API works.
constraint errors which I don't have since failOnError is true
What am I doing wrong? How can I get GORM saves to work because I would like to use the grails tools available.
NOTE: This is not just a test issue, trying to save something in a controller using GORM also does not work. Calling this action:
def save() {
def thing = new Thing()
thing.name = "foobar"
respond thing.save(failOnError: true, flush: true)
}
Returns { "class": "com.Thing", "id": null, "name": "foobar" } and a look at the database tells me it is not saved.
You must add this line at the top of your integration test and it should start saving. By default GORM will not persists even in IntegrationTests
static Boolean transactional = false
You test would look something like below,
class TestIntegrationSpec extends IntegrationSpec {
static Boolean transactional = false
def "my test"() {
...
}
...
}
I'm having an issue with dependencies apparently bleeding between tests, which is causing most of the tests to fail. In each case, debugging shows the first app created in a test class is used for all tests, and this is resulting in the failures.
I've tried adding isolated and sequential and this has had no effect.
Am I doing something remarkably stupid or subtly stupid?
For example, here's SubjectNotPresentTest.scala
class SubjectNotPresentTest extends AbstractViewTest {
"show constrained content when subject is not present" in new WithApplication(testApp(handler())) {
val html = subjectNotPresentContent(FakeRequest())
private val content: String = Helpers.contentAsString(html)
content must contain("This is before the constraint.")
content must contain("This is protected by the constraint.")
content must contain("This is after the constraint.")
}
"hide constrained content when subject is present" in new WithApplication(testApp(handler(subject = Some(user())))) {
val user = new User("foo", Scala.asJava(List.empty), Scala.asJava(List.empty))
val html = subjectNotPresentContent(FakeRequest())
private val content: String = Helpers.contentAsString(html)
content must contain("This is before the constraint.")
content must not contain("This is protected by the constraint.")
content must contain("This is after the constraint.")
}
}
GuiceApplicationBuilder is used in a parent class is used to create the app for testing.
val app = new GuiceApplicationBuilder()
.bindings(new DeadboltModule())
.bindings(bind[HandlerCache].toInstance(LightweightHandlerCache(handler)))
.overrides(bind[CacheApi].to[FakeCache])
.in(Mode.Test)
.build()
You can see an example of the failures at https://travis-ci.org/schaloner/deadbolt-2-scala/builds/66369307#L805
All tests can be found at https://github.com/schaloner/deadbolt-2-scala/tree/master/code/test/be/objectify/deadbolt/scala/views
Thanks,
Steve
It looks like the problem is caused when the current Play application is statically referenced in a test environment in which there are multiple applications - even if they are logically separate.
Because components can't be injected (to the best of my knowledge) into templates, I created a helper object which uses Play.current.injector to define a couple of vals.
val viewSupport: ViewSupport = Play.current.injector.instanceOf[ViewSupport]
val handlers: HandlerCache = Play.current.injector.instanceOf[HandlerCache]
(It's also not possible, TTBOMK, to inject into objects, otherwise I could just inject the components into the object and everyone could go home).
A better approach is to expose what is required as an implicit.
object ViewAccessPoint {
private[deadbolt] val viewStuff = Application.instanceCache[ViewSupport]
private[deadbolt] val handlerStuff = Application.instanceCache[HandlerCache]
object Implicits {
implicit def viewSupport(implicit application: Application): ViewSupport = viewStuff(application)
implicit def handlerCache(implicit application: Application): HandlerCache = handlerStuff(application)
}
}
In the view, import the implicits and you're good to go.
#import be.objectify.deadbolt.scala.DeadboltHandler
#import be.objectify.deadbolt.scala.ViewAccessPoint.Implicits._
#import play.api.Play.current
#(handler: DeadboltHandler = handlerCache(current).apply(), name: String, meta: String = null, timeout: Function0[Long] = viewSupport.defaultTimeout)(body: => play.twirl.api.Html)(implicit request: Request[Any])
#if(viewSupport.dynamic(name, meta, handler, timeout(), request)) {
#body
}
I'm new in create unit test in grails so this question may seem silly.
I have create a unit test of a method that receives input data from a form, how can I emulate the call of the form to the controller in the unit test?
this is my method:
def createNewUser(UserSec user) {
def user = new User()
user.name= params.name
user.surname = params.surname
user.save(flus:true)
}
In this case, name and surname come in the form of parameters from the form, how can I get them from unit tests?
Thanks to all
Bye!
Take a look at the documentation on testing within Grails. It covers specifically how to set parameters for testing controllers. From the examples:
import grails.test.mixin.TestFor
import spock.lang.Specification
#TestFor(PersonController)
class PersonControllerSpec extends Specification {
void 'test list'() {
when:
params.sort = 'name'
params.max = 20
params.offset = 0
controller.list()
then:
// …
}
}