Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem Testing Data Services #18

Open
osscontributor opened this issue Oct 28, 2017 · 3 comments
Open

Problem Testing Data Services #18

osscontributor opened this issue Oct 28, 2017 · 3 comments

Comments

@osscontributor
Copy link
Member

(moving issue from grails/grails-data-mapping#1020 to here)

See https://github.com/jeffbrown/servicetestproblem

Domain:

package servicetestproblem

class Person {
    String name
}

Data Service:

package servicetestproblem

import grails.gorm.services.Service

@Service(Person)
abstract class PersonService {
    abstract List<Person> list()
}

Unit test:

package servicetestproblem

import grails.testing.gorm.DataTest
import grails.testing.services.ServiceUnitTest
import spock.lang.Specification

class PersonServiceSpec extends Specification implements ServiceUnitTest<PersonService>, DataTest {

    def setupSpec() {
        mockDomain Person
    }

    void 'first test'() {
        expect:
        service.list().size() == 0
    }

    void 'second test'() {
        expect:
        service.list().size() == 0
    }
}

There is no reason to have a unit test like that of course but this is a simple example that demonstrates the problem. The second test method will fail with the following:

Condition failed with Exception:

service.list().size() == 0
|
java.lang.reflect.InvocationTargetException

	at servicetestproblem.PersonServiceSpec.second test(PersonServiceSpec.groovy:20)
Caused by: java.lang.reflect.InvocationTargetException
	at grails.testing.services.ServiceUnitTest$Trait$Helper.mockArtefact(ServiceUnitTest.groovy:66)
	at org.grails.testing.ParameterizedGrailsUnitTest$Trait$Helper.getArtefactInstance(ParameterizedGrailsUnitTest.groovy:48)
	at grails.testing.services.ServiceUnitTest$Trait$Helper.getService(ServiceUnitTest.groovy:83)
	... 1 more
Caused by: java.lang.IllegalStateException: Could not register object [servicetestproblem.$PersonServiceImplementation@42339ea2] under bean name 'personService': there is already object [servicetestproblem.$PersonServiceImplementation@42339ea2] bound
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.registerSingleton(DefaultSingletonBeanRegistry.java:130)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.registerSingleton(DefaultListableBeanFactory.java:936)
	at grails.testing.gorm.DataTest$Trait$Helper.mockDataService(DataTest.groovy:101)
	... 4 more
@osscontributor osscontributor self-assigned this Oct 28, 2017
osscontributor pushed a commit that referenced this issue Oct 28, 2017
This check is safe to have in place and makes the problem go away but
there is a root problem that the artifact is being mocked multiple
times because of the way _artefactInstance is managed in
ParameterizedGrailsUnitTest.

Related to #18
@jameskleeh
Copy link
Contributor

@jeffbrown Is this issue resolved with 7b4443f ?

@niravassar
Copy link
Contributor

During creation of the dataservices guide, i tried different ways of testing. i came across this issue that jeff had filed.

It is true that his project works for the first test and fails for the second, in Grails 3.3.1.

However, in grails 3.3.6, the same tests do not work at all. The service is not even accessed in this test. Basically, unit testing with the service is not working. I am not sure that we want it to work because testing with DataTest is not with a Hibernate implementation. In the guide, i recommended testing with HibernateSpec, and also with an integration test.

I created a sample app with this same code that shows it failing.

https://github.com/niravassar/dataservice-unit-test

This is the error

Condition failed with Exception:

service.list().size() == 0
|
java.lang.reflect.InvocationTargetException

	at PersonDataServiceSpec.first test(PersonDataServiceSpec.groovy:15)
Caused by: java.lang.reflect.InvocationTargetException
	at grails.testing.services.ServiceUnitTest$Trait$Helper.mockArtefact(ServiceUnitTest.groovy:66)
	at org.grails.testing.ParameterizedGrailsUnitTest$Trait$Helper.getArtefactInstance(ParameterizedGrailsUnitTest.groovy:48)
	at grails.testing.services.ServiceUnitTest$Trait$Helper.getService(ServiceUnitTest.groovy:83)
	... 1 more
Caused by: java.lang.NoSuchMethodError: org.grails.datastore.mapping.core.AbstractDatastore.getService(Ljava/lang/Class;)Lorg/grails/datastore/mapping/services/Service;
	at grails.testing.gorm.DataTest$Trait$Helper.mockDataService(DataTest.groovy:96)
	... 4 more

PersonDataServiceSpec > first test FAILED
    org.spockframework.runtime.ConditionFailedWithExceptionError at PersonDataServiceSpec.groovy:15
        Caused by: java.lang.reflect.InvocationTargetException at PersonDataServiceSpec.groovy:15
            Caused by: java.lang.NoSuchMethodError at PersonDataServiceSpec.groovy:15

@niravassar niravassar self-assigned this Oct 4, 2018
@niravassar
Copy link
Contributor

@jeffbrown I am thinking we can close this out, based on the notion that we should use HibernateSpec and/or integration suite to test DataServices. If you agree, let me know. thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants