Giter Site home page Giter Site logo

longwa / build-test-data Goto Github PK

View Code? Open in Web Editor NEW
75.0 75.0 40.0 2.56 MB

Enables the easy creation of test data by automatic inspection of constraints. Any properties that are required have their constraints examined and a value is automatically provided for them.

License: Apache License 2.0

Groovy 96.95% Java 3.05%

build-test-data's People

Contributors

asinesio avatar basejump avatar burtbeckwith avatar donalmurtagh avatar dpcasady avatar gregopet avatar lhotari avatar longwa avatar michaelcameron avatar rafaelfelini avatar roidrage avatar sbglasius avatar stokito avatar tednaleid avatar zhuravskiy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

build-test-data's Issues

Assigned ID?

A question rather than an issue... I have some classes with id generator set to assigned (legacy database). Does the plugin provide any way to deal with these ids?

Database not being populated

If I create the Class Author with an id composite like:

static mapping = {
    id composite:['firstName','lastName']
}

the method build does not throw any error but the database is not being populated.

[bug] DomainInstanceBuilder tries to create properties with bindable: false

i have the following constraint in a model merchantToken(blank: false, nullable: true, bindable: false, unique: true), this property is added in the default constructor.

The idea is to build a read-only property assigned at creation time.

The DomainInstanceBuilder is trying to assign a value to that property, but that is happening only when trying to use the build() in BootStrap.groovy, I'm also using the build in tests and it works.

ERROR context.GrailsContextLoaderListener  - Error initializing the application: Exception occurred inside setter of co.tpaga.api.models.Merchant.merchantToken; nested exception is org.hibernate.PropertyAccessException: Exception occurred inside setter of co.tpaga.api.models.Merchant.merchantToken
Message: Exception occurred inside setter of co.tpaga.api.models.Merchant.merchantToken; nested exception is org.hibernate.PropertyAccessException: Exception occurred inside setter of co.tpaga.api.models.Merchant.merchantToken
    Line | Method
->>  242 | save                             in grails.buildtestdata.DomainInstanceBuilder

id doesn't auto-increment when not default id field

Hi,

If a domain object's id is mapped using the name attribute, it doesn't increment the id. e.g


class Client {
   Long clientId

   static mapping = {
        id name: 'clientId'
   }

}

So the following would fail:


assert Client.build().clientId  != Client.build().clientId

build self relation domain parent is null fail

I have a domain Module like this:

class Module {
    String code
    Module parent
}

then I build a module and the parent is null.

Module.build(parent:null)

but I got the error, java.lang.NullPointerException: Cannot invoke method buildCascadingSave() on null object.

I used the version is 2.1.2.

Class decorated too late

Hi,

I've raised this issue before, but I think it got lost during the transition to Github. I'm using Spock and would like to build an instance in the setupSpec method:

def setupSpec() {
   def instance = Domain.build()
}

This fails with a method missing exception. Building an object in the setup() method works fine, but not in setupSpec(). The problem seems to be that @build annotation decorates the class after setupSpec() is called. Is it possible to fix this?

Please see also the discussion in the spock user group

Support Grails 3

given Grails-3.0.0 just reached M2 and a final is planned to be released soon, it would be nice to see this plugin work with Grails 3 :)

thanks, zyro

Constraints unique: true and email: true cause a validation failure when repeated

Our domain object has a username field that must be both a valid email address and unique. When I do Identity.build() twice in a row the second instance attempts to populate the username field with the string literal username, which is not a valid email address.

The workaround for me is easy: just specify a valid unique email address upon object creation. I'll need to put together a sanitized version of test code to provide a runnable example, but it's pretty easy to test. Just create a domain object like so:

class AppUser {
    String username
    static constraints = {
        username email: true, unique: true
    }
}

AppUser.build()
AppUser.build() // <-- throws a validation exception

gradle grails-compile -PgrailsArgs='--non-interactive' failed for Grails 2.4.0

First of all, thanks for developing the plugin! :-)

Recently I just upgraded Grails to 2.4.0 and the build-test-data plugin is still version 2.1.2 which is the latest at the moment.

I ran the command:
gradle grails-compile -PgrailsArgs='--non-interactive'
and I got the error as below.

  [groovyc] org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
  [groovyc] Compile error during compilation with javac.
  [groovyc] <my_project_path>/buildPlugins/build-test-data-2.1.2/src/java/grails/buildtestdata/mixin/BuildTransformation.java:14: error: package org.junit does not exist
  [groovyc] import org.junit.Before;
  [groovyc]                 ^
  [groovyc] /var/folders/2z/n9vfhml12px06831pr5ckw6m0000gn/T/groovy-generated-7894976611881720036-java-source/grails/buildtestdata/mixin/BuildTestDataUnitTestMixin.java:14: error: package org.junit does not exist
  [groovyc] @org.junit.After() public  void cleanupBuildTestData() { }
  [groovyc]           ^
  [groovyc] <my_project_path>/buildPlugins/build-test-data-2.1.2/src/java/grails/buildtestdata/mixin/BuildTransformation.java:95: error: cannot find symbol
  [groovyc]         return isPublicInstanceMethod(methodNode) && hasAnnotation(methodNode, Before.class) && !hasAnnotation(methodNode, MixinMethod.class);
  [groovyc]                                                                                ^
  [groovyc]   symbol:   class Before
  [groovyc]   location: class BuildTransformation
  [groovyc] 3 errors
  [groovyc]

I hope the error message is useful.
Kindly let me know if you need other details from me regarding the error.
Thanks. :-)

DomainInstanceBuilder is skipping save()

I'm trying to build a domain class for a Unit Test in Grails 2.3.1 whit build-test-data 2.0.6.

My code is extremely simple:

def user = User.build(id: 1)

But when I run grails test-app, this is printed in the console:

DEBUG buildtestdata.BuildTestDataService  - Adding build methods to Artefact > User
INFO  buildtestdata.DomainInstanceBuilder  - After api.core.User.save() api.core.User : 1, skipped because it already has a key and isn't assigned

So I decided to look for the code in DomainInstanceBuilder that prints that log, and found this conditional block:

if (!(hasAssignedKey || domainInstance.ident() == null)) {
   log.info "After ${domainInstance.class.name}.save() $domainInstance, skipped because it already has a key and isn't assigned"
}
else {
    log.info "After ${domainInstance.class.name}.save() $domainInstance, success!"
}

I think that hasAssignedKey variable is always false in my case, because I have no mappings block in my domain class (already tried adding an empty static mappings block). So maybe the problem is in the ident() method, which I don't know what it does.

As the log entry says, my instance is skipped and therefore all my tests fail, so I'm getting a bit desperate :(

Any ideas?

Invalid id: string in asscociation

It does not set predefined clientId (TemplateId) to has_one association.
Is it expected behavour?

@TestFor(Client)
@Build(Client)
class ClientTestSpec extends Specification {
    public static final String TEMPLATE_ID = 'TemplateId'

    def setup() {
        def c = Client.build(clientId: TEMPLATE_ID)
        c.save(failOnError: true)
    }

    def cleanup() {

    }

    void "test something"() {
        when:
        def c = Client.findByClientId TEMPLATE_ID
        then:
        c.clientId == TEMPLATE_ID
        c.tplusClient.clientId == TEMPLATE_ID <-- return clientId
    }
}


class Client {
   String clientId
   static hasOne = [ tplusClient: TplusClient ]
   static mapping = {
        id name: 'clientId', generator: 'assigned'
    }
}

class TplusClient {
  String clientId
  static mapping = {
        id name: 'clientId', column: 'client_id', generator: 'assigned'
}

Automatically add `@Domain` annotations for both HibernateTextMixin and MongoDbTestMixin tests

Initial support for working with the @HibernateTestMixin is in the master branch, but it currently requires the user to add all the necessary @Domain annotations.

This is unlike the current @Build annotation for non-hibernate tests, as that automatically does the equivalent of a @Mock annotation for whatever classes need it.

It was also mentioned by @lhotari on this issue that grails 2.4 also adds a @MongoDbTestMixin that would be nice to support.

Best case scenario is that we use the same @Build annotation as normal, but detect if the user is using either a hibernate or mongo annotations (or maybe via some other marker to support other classes that want @Domain annotations?), and automatically adds @Domain calls for all necessary domain classes.

MissingMethodException with grails 2.3.0

After update to grails 2.3.0 i'm getting MissingMethodExceptions in unit-tests:

No signature of method: static org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinder.getMapping() is applicable for argument types: (java.lang.Class) values: [class MyClass]
Possible solutions: getMapping(java.lang.Class), getMapping(org.codehaus.groovy.grails.commons.GrailsDomainClass)
groovy.lang.MissingMethodException: No signature of method: static org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinder.getMapping() is applicable for argument types: (java.lang.Class) values: [class MyClass]
Possible solutions: getMapping(java.lang.Class), getMapping(org.codehaus.groovy.grails.commons.GrailsDomainClass)
    at grails.buildtestdata.DomainInstanceBuilder.isAssignedKey(DomainInstanceBuilder.groovy:264)
    at grails.buildtestdata.DomainInstanceBuilder.save(DomainInstanceBuilder.groovy:240)
    at grails.buildtestdata.DomainInstanceBuilder.save(DomainInstanceBuilder.groovy:230)
    at grails.buildtestdata.DomainInstanceBuilder.build(DomainInstanceBuilder.groovy:135)
    at grails.buildtestdata.DomainInstanceBuilder.build(DomainInstanceBuilder.groovy:133)
    at grails.buildtestdata.BuildTestDataService.addBuildMethods_closure5(BuildTestDataService.groovy:46)

see also:
http://grails.1312388.n4.nabble.com/Grails-2-3-GrailsDomainBinder-getMapping-no-longer-static-td4648984.html

Using the plugin from within scripts

I would like to use the plugin from within a script that I run with run-script in the grails console.

Unfortunately, I get org.springframework.dao.DataAccessResourceFailureException: Could not obtain current Hibernate Session.

I am using Grails 2.4.4 with HIbernate 4.
Any hints?

Excessive logging at INFO level

The Build Test Data plugin (version 2.0.5) logs a GRAPH statement at INFO level every time an instance is built.

It's a useful statement, but only when I'm trying to debug an issue. Log files are littered with hundreds of these statements:

INFO 2013-04-22 15:01:25,027 [] [GRAPH] - build: com.mycompany.MyDomainClass

Of course, I can set the log level for grails.buildtestdata to ERROR to get around this issue, but I think it would be better served to log this information at DEBUG level.

Does not handle Character type

If a class has Character property then builder generates the following:

Could not find matching constructor for: java.lang.Character()
groovy.lang.GroovyRuntimeException: Could not find matching constructor for: java.lang.Character()
    at grails.buildtestdata.handler.NullableConstraintHandler.determineNonStandardValue(NullableConstraintHandler.groovy:117)
    at grails.buildtestdata.handler.NullableConstraintHandler.handle(NullableConstraintHandler.groovy:21)
    at grails.buildtestdata.DomainInstanceBuilder.createMissingProperty(DomainInstanceBuilder.groovy:198)
    at grails.buildtestdata.DomainInstanceBuilder.populateInstance(DomainInstanceBuilder.groovy:158)
    at grails.buildtestdata.DomainInstanceBuilder.build(DomainInstanceBuilder.groovy:136)
    at grails.buildtestdata.DomainInstanceBuilder.build(DomainInstanceBuilder.groovy:135)
    at grails.buildtestdata.BuildTestDataService.addBuildMethods_closure1(BuildTestDataService.groovy:24)
    at groovy.lang.Closure.call(Closure.java:423)

Grails 3 - build fails for domain objects with composite keys

We use the Build Test Data Plugin extensively in our tests for a Grails 2.5.3 app.. When using Grails 3.1.x, invoking the build() method for domain objects that have composite keys seems to break. For example, we have a domain class named AccountGroup, which not surprisingly, has references to an Account object and a Group object. It doesn't have its own primary key - it uses a composite of ids for the account and the group objects. When I try to use AccountGroup.build(...) in an integration test, the call ends failing with a NullPointerException in the org.grails.datastore.gorm.GormInstanceApi.ident() method. The implementation for that method looks like this:

protected Serializable ident(D instance) {
(Serializable)instance[persistentEntity.getIdentity().name]
}

It looks like the ident() method needs to protect against nulls returned by the getIdentity() method.

Is there a way for the plugin to handle this correctly?

Run executeQuery failed when execute integration test

I have a method in a service using a executeQuery("HQL"), but when my test call the service method throws an exception like that:

String-based queries like [executeQuery] are currently not supported in this implementation of GORM. Use criteria instead.

But, if I remove the annotation @Build of my test class the test pass alright.

  • I'm using the 2.2.3 grails/plugin version.

Grails 3.0.9 and BTD 3.0.0 Not Working In Tests

During the invocation of the test on a unit test class that doesn't even use build test data the below is happening and blowing up via spring.

We are using

dependencies {
testCompile "org.grails.plugins:build-test-data:3.0.0"
testCompile "org.grails:grails-plugin-testing"
}

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'grailsApplicationPostProcessor': Initialization of bean failed; nested exception is grails.plugins.exceptions.PluginException: Failed to initialize class [grails.buildtestdata.BuildTestDataService] from plugin [buildTestData] : grails/artefact/Service

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:547)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:116)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:606)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:462)
at grails.test.runtime.GrailsApplicationTestPlugin.createMainContext(GrailsApplicationTestPlugin.groovy:118)
at grails.test.runtime.GrailsApplicationTestPlugin.initGrailsApplication(GrailsApplicationTestPlugin.groovy:95)
at grails.test.runtime.GrailsApplicationTestPlugin.onTestEvent(GrailsApplicationTestPlugin.groovy:345)
at grails.test.runtime.TestRuntime.deliverEvent(TestRuntime.groovy:295)
at grails.test.runtime.TestRuntime.executeEventLoop(TestRuntime.groovy:280)
at grails.test.runtime.TestRuntime.processEvents(TestRuntime.groovy:265)
at grails.test.runtime.TestRuntime.doPublishEvent(TestRuntime.groovy:238)
at grails.test.runtime.TestRuntime.publishEvent(TestRuntime.groovy:211)
at grails.test.runtime.TestRuntime.getValue(TestRuntime.groovy:122)
at grails.test.runtime.GrailsApplicationTestPlugin.onTestEvent(GrailsApplicationTestPlugin.groovy:338)
at grails.test.runtime.TestRuntime.deliverEvent(TestRuntime.groovy:295)
at grails.test.runtime.TestRuntime.processEvents(TestRuntime.groovy:264)
at grails.test.runtime.TestRuntime.doPublishEvent(TestRuntime.groovy:248)
at grails.test.runtime.TestRuntime.publishEvent(TestRuntime.groovy:211)
at grails.test.runtime.TestRuntimeJunitAdapter.before(TestRuntimeJunitAdapter.groovy:106)
at grails.test.runtime.TestRuntimeJunitAdapter$1$2.evaluate(TestRuntimeJunitAdapter.groovy:44)
at org.spockframework.runtime.extension.builtin.TestRuleInterceptor.intercept(TestRuleInterceptor.java:38)
at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:87)
at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:88)
at org.spockframework.runtime.extension.builtin.AbstractRuleInterceptor$1.evaluate(AbstractRuleInterceptor.java:37)
at grails.test.runtime.TestRuntimeJunitAdapter$3$4.evaluate(TestRuntimeJunitAdapter.groovy:73)
at org.spockframework.runtime.extension.builtin.ClassRuleInterceptor.intercept(ClassRuleInterceptor.java:38)
at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:87)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

Caused by: grails.plugins.exceptions.PluginException: Failed to initialize class [grails.buildtestdata.BuildTestDataService] from plugin [buildTestData] : grails/artefact/Service
at org.grails.plugins.BinaryGrailsPlugin.initializeProvidedArtefacts(BinaryGrailsPlugin.java:133)
at org.grails.plugins.BinaryGrailsPlugin.(BinaryGrailsPlugin.java:66)
at grails.plugins.DefaultGrailsPluginManager.createBinaryGrailsPlugin(DefaultGrailsPluginManager.java:390)
at grails.plugins.DefaultGrailsPluginManager.findCorePlugins(DefaultGrailsPluginManager.java:377)
at grails.plugins.DefaultGrailsPluginManager.attemptLoadPlugins(DefaultGrailsPluginManager.java:329)
at grails.plugins.DefaultGrailsPluginManager.loadPlugins(DefaultGrailsPluginManager.java:239)
at grails.boot.config.GrailsApplicationPostProcessor.initializeGrailsApplication(GrailsApplicationPostProcessor.groovy:87)
at grails.boot.config.GrailsApplicationPostProcessor.setApplicationContext(GrailsApplicationPostProcessor.groovy:199)
at org.springframework.context.support.ApplicationContextAwareProcessor.invokeAwareInterfaces(ApplicationContextAwareProcessor.java:119)
at org.springframework.context.support.ApplicationContextAwareProcessor.postProcessBeforeInitialization(ApplicationContextAwareProcessor.java:94)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:408)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1566)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
... 36 more
Caused by: java.lang.NoClassDefFoundError: grails/artefact/Service
at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:411)
at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:677)
at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:787)
at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:775)
at org.grails.plugins.BinaryGrailsPlugin.initializeProvidedArtefacts(BinaryGrailsPlugin.java:131)
... 48 more
Caused by: java.lang.ClassNotFoundException: grails.artefact.Service
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 62 more

Populate value for optional fields

Just have question for the optional fields.

I noticed the build method only populate the value for the required fields.
Is there any way to build a domain with populated the simple value for optional fields in this domain

Cheers
Wallace

readOnly on transactional service fails the unit test

Hi,
I'm very new to Grails (with only a Java background) so I'm not sure if it's a bug or a feature. But I noticed a strange behavior using the build-test-data plugin. When I set a service method as readOnly=true, the domain objects previously created with build() are not saved, unless I read my Domain objects before calling my service.
Here is the code to reproduce my problem:

============= in /grails-app/domain =============
package mypackage

class MyDomain {

String myField

}

============= in /grails-app/services/mypackage =============
package mypackage

import grails.transaction.Transactional

@transactional
class MyService {

def listEntities() {
    MyDomain.list()
}

@Transactional(readOnly=true)
def listEntitiesReadOnly() {
    MyDomain.list()
}

============= in /test/unit/mypackage =============
package mypackage

import grails.buildtestdata.mixin.Build
import grails.test.mixin.TestFor
import spock.lang.Specification

@testfor(MyService)
@build(MyDomain)
class MyServiceSpec extends Specification {

void "test list() using default"() {
    given:
    MyDomain.build()

    when:
    def res = service.listEntities()

    then:
    res.size()==1
}
void "test list() with service read-only"() {
    given:
    MyDomain.build()

    when:
    def res = service.listEntitiesReadOnly()

    then:
    res.size()==1
}
void "test list() with service read-only with assert before"() {
    given:
    MyDomain.build()
    MyDomain.list()

    when:
    def res = service.listEntitiesReadOnly()

    then:
    res.size()==1
}

}

I'm using Grails 2.4.4 with build-test-data 2.4.0.

The first and third test work, not the second one. Does anybody know why?
Thanks in advance.

plugin fails to generate values for fields in Hibernate-mapped domain classes after 'grails clean'

I have hibernate java domains that are shared with another java app and live in a jar.
They are configured as per http://grails.org/doc/latest/guide/hibernate.html#mappingWithHibernateAnnotations

In addition, I found that I had to add 'id' and 'version' fields to the java class in order for the Grails @mock annotation to recognize them a domain models.

However, when using @build, i've ran into this issue.
In a Spock spec, I build a model as follows "MyModel.build(attr1: '123', attr2: 'abc)"
The MyModel class has 2 more fields which are joda.DateTime.

The first time i execute grails test-app, the test will fail because the datetime fields are null.
However, if i just run 'grails test-app' again, the test passes and logging shows that the date fields are populated correctly.
After running 'grails clean', the next test run fails again.

I am in the midst of debugging through the grails code to try to find the root cause, but was wondering if you would have any idea of the top of your head.

Thanks in advance!

Domain instance not being saved

I am currently having an issue with this plugin while running integration tests.

class AppTypeServiceSpec extends Specification {
    def testAppType

    def setup() {
        testAppType = AppType.build()
    }
......
        when: "with valid id"
            def json = '{"id":' + testAppType.id + '}'
            def result = service.deleteAppType(json)

            then:
            result.id.equals(testAppType.id)

The above test is resulting in the error: "java.lang.IllegalArgumentException: AppType not found with id 1". However, if I slightly modify the setup method to the below, the test works.

class AppTypeServiceSpec extends Specification {
    def testAppType

    def setup() {
        testAppType = AppType.build()
        testAppType = AppType.findById(testAppType.id)
    }

I believe this issue is related to issue #10. I am seeing the same errors as in that issue when I enable debugging for the plugin.

The project is currently running Grails 2.4.2 and version 2.2.2 of this plugin.

Add a way to configure default concrete subclasses for abstract references

If you have a domain class with a polymorphic association that is required, BTD will currently just pick a random concrete subclass in order to satisfy the graph.

However, this has a number of drawbacks. The biggest is that it introduces non-deterministic test behavior since the order of the subclasses is not always the same.

This feature will make two changes:

  1. Introduce another optional configuration in testDataConfig called abstractDefault which allows you to strictly control the type of concrete class built for any abstract class.
testDataConfig {

    // For unit tests, this indicates an implicit @Build relationship. In this case, anytime a Hotel is used in @Build
    // we also want to include Article and Author. This is useful if you define defaults in sampleData that explicitly
    // build other objects.
    unitAdditionalBuild = [
        'config.Hotel': ['config.Article'],
        'config.Article': [Author]
    ]

    // For polymorphic associations, this allows you to default the concrete class that is built automatically.
    // By default, BTD will find all concrete subclasses and build the first one alphabetically by name.
    abstractDefault = ['abstractclass.AbstractClass': AnotherConcreteSubClass]

    sampleData {
  1. If a default is not given, the subclasses are sorted alphabetically, by name, to ensure that the test run is at least deterministic.

We've found that the variability can be very annoying if you have a large graph with many polymorphic references.

Since I'm making changes for issue #12, this seems like a good time to implement and test both.

support for insertable/updateable:false

Objects that have GORM mapping properties specifying insertable:false or updatable:false are not persisted using build() and, thus, subsequent calls to get do not find the object. Such a domain object might be used for read-only data that is not intended to be manipulated by the Grails application under test.

Consider:

class Book {
    static mapping {
        title insertable: false
        title updatatble: false
        author insertable: false
        author updatatble: false
    }
    String title
    String author
}

Instead of creating an object with:

Book.build(title: 'Dr. No', author: 'Ian Flemming')

A workaround such as this must be used where validatable: false can be specified:

new Book(title: 'Dr. No', author: 'Ian Flemming').save(failOnError: true, validate: false)

Is there a way to use build() to do the same thing?

UPDATE: This behavior is observed using build-test-data 2.2.3 with Grails 2.1.5.

Works in *ControllerIntTests but fails in others

I'm working on upgrading a project from 1.3.6 to 2.5.1 (build test data from 1.1.1 to 2.4.0) but running into issues with non-controller int tests.

.build* methods are used everywhere in many integration test cases. But when I do

test-app integration:

the method runs well in all the tests suffixed with *ControllerIntTests but fails for others like *ServiceTests showing exceptions like:

groovy.lang.MissingMethodException: No signature of method: com.zub.Brand.buildLazy() is applicable for argument types: (java.util.LinkedHashMap) values: [[subdomain:googoo]]
    at org.grails.datastore.gorm.GormStaticApi.methodMissing(GormStaticApi.groovy:92)
    at com.zub.ProductKeywordSearcherServiceTests.testExactMatchOneFromSeveralProducts(ProductKeywordSearcherServiceTests.groovy:67)
    at junit.framework.TestCase.runTest(TestCase.java:176)
    at junit.framework.TestCase.runBare(TestCase.java:141)
    at junit.framework.TestResult$1.protect(TestResult.java:122)
    at junit.framework.TestResult.runProtected(TestResult.java:142)
    at junit.framework.TestResult.run(TestResult.java:125)
    at junit.framework.TestCase.run(TestCase.java:129)
    at junit.framework.TestSuite.runTest(TestSuite.java:252)
    at junit.framework.TestSuite.run(TestSuite.java:247)

Anything I'm missing from my side or can there be any 'hack' I can do to get this running? Much appreciated.

grails 2.3

Hi,
Will you release for grails 2.3.0?
I found it works with this change
class grails.buildtestdata.DomainInstanceBuilder
line 264

  • GrailsDomainBinder.getMapping(domainInstance.class)?.identity
  • new GrailsDomainBinder().getMapping(domainInstance.class)?.identity

Unit test @Build with abstract domain class fails with NPE in 2.3.x

In 2.3.x, if BTD tries to build an abstract domain class, it fails to find any concrete subclasses and gives the following exception:

|  java.lang.NullPointerException: Cannot get property 'clazz' on null object
    at grails.buildtestdata.DomainInstanceBuilder.<init>(DomainInstanceBuilder.groovy:85)
    at grails.buildtestdata.BuildTestDataService.addBuildMethods(BuildTestDataService.groovy:16)
    at grails.buildtestdata.BuildTestDataService.decorateWithMethods(BuildTestDataService.groovy:10)
    at grails.buildtestdata.mixin.BuildTestDataUnitTestMixin$_mockForBuild_closure3.doCall(BuildTestDataUnitTestMixin.groovy:78)
    at grails.buildtestdata.mixin.BuildTestDataUnitTestMixin.mockForBuild(BuildTestDataUnitTestMixin.groovy:77)

support for unique properties

Following on from #22 I'm curious about why unique properties are unsupported? Presumably you could generate UUIDs for String properties and for numeric properties you could have a singleton instance of AtomicInteger and call getAndIncrement() on that every time a new value is required (performing a widening conversion to a float, double, etc. if required).

Of course if there are more values required for an integer property than there are available in the range Integer.MIN_VALUE..Integer.MAX_VALUE then you're stuffed, but this is a pretty unlikely case.

I guess I must be missing something, but what is it? If this sounds like a viable solution, I might give it a go myself.

add support for property with email constraint

I have a User class with a username property which has the following constraints:

    username blank: false, unique: true, email: true

When I try to build an instance with User.build() it fails because this field is set to "username" by default which is not a valid email address.

I know that I can workaround this by setting the field myself, but it seems like it should be possible to support this constraint out-of-the-box by defaulting it (in this case) to something like: [email protected]

Issue for -Dgrails.env=ci test-app :unit :integration

Hi There

I import the plugin like this in buildconfig

test ":build-test-data:2.1.2", { export = false }

But if i test app with the command test-app -Dgrails.env=ci test-app :unit :integration

The builder will throw exception in integration test but not unit test
Example :
.build() is applicable for argument types: (java.util.LinkedHashMap)

It looks like the builder is not injected into Domains in integration test when test-app with different env name

Cheers
Wallace

Exception when build an object that has unique constraint on integration test

On integration test (I didn't checked for unit tests) if you build() a domain that has unique constraint, you get:

groovy.lang.MissingMethodException: No signature of method: org.grails.datastore.gorm.validation.constraints.UniqueConstraint$_withManualFlushMode_closure2.doCall() is applicable for argument types: (org.hibernate.internal.SessionImpl) values: [SessionImpl(<closed>)]
Possible solutions: doCall(org.grails.datastore.mapping.core.Session), findAll(), findAll(), isCase(java.lang.Object), isCase(java.lang.Object)
    at groovy.lang.Closure.call(Closure.java:426)
    at groovy.lang.Closure.call(Closure.java:442)
    at org.grails.orm.hibernate.HibernateGormStaticApi$1.doInHibernate(HibernateGormStaticApi.groovy:176)
    at org.grails.orm.hibernate.GrailsHibernateTemplate.doExecute(GrailsHibernateTemplate.java:198)
    at org.grails.orm.hibernate.GrailsHibernateTemplate.execute(GrailsHibernateTemplate.java:142)
    at org.grails.orm.hibernate.HibernateGormStaticApi.withSession(HibernateGormStaticApi.groovy:174)
    at org.grails.datastore.gorm.GormEntity$Trait$Helper.withSession(GormEntity.groovy:700)
    at org.grails.datastore.gorm.validation.constraints.UniqueConstraint.withManualFlushMode(UniqueConstraint.groovy:104)
    at org.grails.datastore.gorm.validation.constraints.UniqueConstraint.processValidate(UniqueConstraint.groovy:39)
    at grails.validation.AbstractConstraint.validate(AbstractConstraint.java:107)
    at grails.validation.ConstrainedProperty.validate(ConstrainedProperty.java:979)
    at grails.buildtestdata.DomainInstanceBuilder.getErrors(DomainInstanceBuilder.groovy:248)
    at grails.buildtestdata.DomainInstanceBuilder.createMissingProperty(DomainInstanceBuilder.groovy:207)
    at grails.buildtestdata.DomainInstanceBuilder.populateInstance(DomainInstanceBuilder.groovy:160)
    at grails.buildtestdata.DomainInstanceBuilder.build(DomainInstanceBuilder.groovy:136)
    at grails.buildtestdata.DomainInstanceBuilder.build(DomainInstanceBuilder.groovy:135)
    at grails.buildtestdata.BuildTestDataService.addBuildMethods_closure1(BuildTestDataService.groovy:24)
    at groovy.lang.Closure.call(Closure.java:426)
    at demobtd.FooSpec.$tt__setup(FooSpec.groovy:14)
    at demobtd.FooSpec.setup_closure1(FooSpec.groovy)
    at groovy.lang.Closure.call(Closure.java:426)
    at groovy.lang.Closure.call(Closure.java:442)
    at grails.transaction.GrailsTransactionTemplate$2.doInTransaction(GrailsTransactionTemplate.groovy:96)
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
    at grails.transaction.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:93)
    at demobtd.FooSpec.setup(FooSpec.groovy)

Using TestDataConfig.groovy to implement the generation like:

testDataConfig {
    sampleData {
        'demobtd.Customer' {
            def i = 1
            name = { "name${i++}" }
        }
    }
}

doesn't help

I'm using build-test-data 3.0.0 and Grails 3.0.11

The example listed on the BasicUsage page does not work as advertised

I followed the steps outlined on the BasicUsage page, but when I attempted to run

def a = Author.build()
println "First Name: $a.firstName"
println "Last Name: $a.lastName"
println "Author ID: $a.id"

from the grails console, the following exception is thrown

Exception thrown

groovy.lang.MissingPropertyException: No such property: Author for class: ConsoleScript4
    at ConsoleScript4.run(ConsoleScript4:3)
    at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1270)

After altering the Groovy code to include the fully qualified path to the Author class

def a = grails.bookstore.example.Author.build()
println "First Name: $a.firstName"
println "Last Name: $a.lastName"
println "Author ID: $a.id"

It worked!!! What am I missing? Should the fully qualified path be a requirement?

MissingMethodException when trying to use build() in Bootstrap

Hi,

I ' am trying to fill test data in Grails 3 application using the BootsStrap.groovy, but i got this exception when using any domain class with the build() method

UPDATE: I changed the dependencies from testCompile "org.grails.plugins:build-test-data:3.0.0" to compile "org.grails.plugins:build-test-data:3.0.0" and everything worked fine

avoid use of deprecated ApplicationHolder

In the dev environment, this plugin generates a lot of warnings in the log like this:

WARN util.GrailsUtil - [DEPRECATED] Method ApplicationHolder.getApplication() is deprecated and will be removed in a future version of Grails.

There is no way to distinguish in the log what is doing the deprecated usage, so those warnings cannot be ignored for one plugin while still warning for the app or another plugin. They can only be hidden as a whole, by setting System property grails.log.deprecated=false.

No such property: application for class: grails.buildtestdata.BuildTestDataGrailsPlugin

Using Grails 3.2.0.RC1 and 3.0.0 version of the plugin I get the following error during integration tests:

Caused by: groovy.lang.MissingPropertyException: No such property: application for class: grails.buildtestdata.BuildTestDataGrailsPlugin
    at grails.buildtestdata.BuildTestDataGrailsPlugin$_closure1.doCall(BuildTestDataGrailsPlugin.groovy:32)

Full Stacktrace:

https://gist.github.com/rpalcolea/cf7be13d2cbbd803c05c4976540441f4

can't build domain class in Grails 2.1.4 app

I'm trying to use the v. 2.0.4 to build test data in a unit test of a Grails 2.1.4 application. The app has the following domain classes

class Brochure {
  static constraints = {}
  static hasMany = [pageTags: PageTag]    
}

class PageTag {
    static constraints = {
    }
    static belongsTo = [brochure: Brochure]
}

Then in my unit test I try to build an instance of PageTag with

@Build([Brochure, PageTag])
class BrochureTests {

    void testSomething() {
       PageTag pageTag = PageTag.build()
    }
}

But it fails with the error

groovy.lang.MissingMethodException: No signature of method: btd.bug.Brochure.addToPageTags() is applicable for argument types: (btd.bug.PageTag) values: [btd.bug.PageTag : (unsaved)] Possible solutions: getPageTags()

My example looks exactly the same as that shown in the plugin's docs, so I've no idea why this isn't working. A sample app that demonstrates the issue is available here

https://bitbucket.org/tednaleid/grails-test-data/issue-attachment/69/tednaleid/grails-test-data/1366373541.27/69/btd-bug.zip

unable to resolve class nl.flotsam.xeger.Xeger

I've been trying to make the plugin to work but unfortunately
I get the following error :

unable to resolve class nl.flotsam.xeger.Xeger 
import nl.flotsam.xeger.Xeger

I've added the build test data in my BuildConfig.groovy class under the plugins section:

compile ":build-test-data:2.0.10"

My Grails version is 2.3.4.
Am I doing something wrong ?

Problem about overwriting the method in Domain Class

Hi There
Thanks for providing this wonderful plugin.
I try to use it in unit test and to create a domain instance with Domain.Build().
But i also want to use Domain.metaClass.method = {->} to overwrite some methods in this domain( called in before method in test class). Which doesn't look liking working with this plugin.

Cheers
Wallace

How to build-test-data for Inheritance (parent-child) domain classes

class Books {
    String BookName
}
class Author extends Books {
    String AuthorName
}

class AuthorService {
    def add(author) {
        books = Books.get(author.authId.toLong()) 
        println books.authorName
        // Functionality will work properly because get on parent, grails will get all the fields from parent 'Books' as well as child 'Author' based on 'class' column. Assuming class column is updated with "Author"
    }
}
@TestFor(AuthorService)
@Build([Author])
class AuthorServiceSpec extends Specification {

def "Add Author details"() {
        given:
        def author = Author.build(authId: id, AuthorName: authorName, BookName: bookName)
        when:
        AuthorService authorService = service.add(author) // When executing via test case, line books = Books.get(author.authId.toLong())  gives null for 'books', where as functionality works properly.
}

Please let us know how to build during parent, child scenario

No such property: log for class: grails.buildtestdata.BuildTestDataService

I get this exception in test case:
@testfor(MyController)
@mock([User, Request])
@build(Request)
class MyControllerSpec extends ExtendedSpockSpecification {
...
}

Stacktrace:

groovy.lang.MissingPropertyException: No such property: log for class: grails.buildtestdata.BuildTestDataService
at grails.buildtestdata.BuildTestDataService.addBuildMethods(BuildTestDataService.groovy:14)
at grails.buildtestdata.BuildTestDataService.decorateWithMethods(BuildTestDataService.groovy:10)
at grails.buildtestdata.mixin.BuildTestDataUnitTestMixin.mockForBuild_closure3(BuildTestDataUnitTestMixin.groovy:78)
at groovy.lang.Closure.call(Closure.java:411)
at groovy.lang.Closure.call(Closure.java:427)
at grails.buildtestdata.mixin.BuildTestDataUnitTestMixin.mockForBuild(BuildTestDataUnitTestMixin.groovy:77)

Add a way to specify automatic @Build requirements for unit tests

We have some situation where we need to have defaults values for domain objects which include buildLazy() or buildWithoutSave() construction of other domain objects. This is usually to overcome some complicated graph construction or some other issue with circular references, etc.

For example, we might have:

'com.foo.User' {
    someProperty = {-> Group.buildWithoutSave() }
}

This works pretty well and gives us a lot of flexibility. However, it puts a "hidden" requirement on any unit test that needs to build a User. Now they must do:

@Build([User, Group])

But it's not obvious and Group isn't really needed explicitly in the test case.

I'd like to have some way to indicate to the @build annotation that it needs to pull in additional classes, something like:

'com.foo.User' {
    requires([Group, Foo, Bar])
    someProperty = {-> Group.buildWithoutSave() }
}

That way when the user does @build(Unit) they'll get the Group automatically.

What do you think of this approach? I wanted to get some input before doing any work towards it. Our TestDataConfig has gotten large enough in my current project to warrant doing something about it.

graphLog/graphDepth isn't thread safe

I'm using build in some test controllers/services and hitting it with multiple threads. The current implementation of the graphLog assumes that it's only a single thread and the static graphDepth isn't getting incremented/decremented within a single thread, instead it's becoming negative somehow and my log is filling up with stacktraces like this:

multiply() should be called with a number of 0 or greater not: -190. Stacktrace follows:
Message: multiply() should be called with a number of 0 or greater not: -190
    Line | Method
->>  330 | logToGraph in grails.buildtestdata.DomainInstanceBuilder
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|    144 | build      in     ''
|    143 | build . .  in     ''
|     45 | doCall     in grails.buildtestdata.BuildTestDataService$_addBuildMethods_closure5
|     32 | doCall . . in com.naleid.service.PurchaseService$_createPurchase_closure2
|     21 | stopWatch  in com.naleid.utils.StopWatchAspect
|     11 | index . .  in com.naleid.controller.PurchaseController
|     21 | stopWatch  in com.naleid.utils.StopWatchAspect
|    200 | doFilter . in grails.plugin.cache.web.filter.PageFragmentCachingFilter
|     63 | doFilter   in grails.plugin.cache.web.filter.AbstractFilter
|   1110 | runWorker  in java.util.concurrent.ThreadPoolExecutor
|    603 | run        in java.util.concurrent.ThreadPoolExecutor$Worker
^    722 | run . . .  in java.lang.Thread

IntegrationSpec Tests Thows Error using Grails 2.5.4

We were using the plugin with our spock integrationSpec tests without any issue under grails 2.3.1 and java 7. Post an upgrade to Java 8 and grails 2.5.4 we are now receiving this error when running the tests.

java.lang.IllegalStateException: Method on class [SomeDomainClass] was used outside of a Grails application. If running in the context of a test using the mocking API or bootstrap Grails correctly.
at grails.buildtestdata.DomainInstanceBuilder.save(DomainInstanceBuilder.groovy:242)
at grails.buildtestdata.DomainInstanceBuilder.save(DomainInstanceBuilder.groovy:231)
at grails.buildtestdata.DomainInstanceBuilder.build(DomainInstanceBuilder.groovy:137)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.