mercredi 11 décembre 2019

Grails domain class unsaved in test

I am relatively new to grails and am building an event management app. I have an issue that one of my domain classes is not saved after calling the .save() method, but only during testing.

So simplified I have 3 domain classes: Person, Event and Participation. The one that I have issues with is Participation:

class Participation implements Serializable {

    private static final long serialVersionUID = 1

    Person person
    Event event

    static Participation create(Person person, Event event, boolean flush = false) {
        def instance = new Participation(person: person, event: event)
        instance.save([failOnError: true, flush: flush])
        instance
    }

    static constraints = {
        person nullable: false
        event nullable: false, validator: { Event e, Participation pt ->
            if (pt.person?.id) {
                if (Participation.exists(pt.person.id, e.id)) {
                    return ['participation.exists']
                }
            }
        }
    }

    static mapping = {
        id composite: ['person', 'event']
        version false
    }
}

I am trying to test what happens if a Person joins an Event that is already full, this is handled in the service:

@Transactional
class UserService {

    def join(Person p, Event e) {
        if (e.getParticipants().size() >= e.maxParticipants) {
            throw new EventFullException()
        }
        Participation.create(p, e)
    }

}

My test looks as follows:

class UserServiceSpec extends HibernateSpec implements ServiceUnitTest<UserService>{

    void "a person cannot join a full event"() {
        when:
        Person p1 = save(new Person(name: "Test1"))
        Person p2 = save(new Person(name: "Test2"))
        Event e = save(new Event(name: "Event", start: LocalDateTime.now().plusDays(1), maxParticipants: 1))
        service.join(p1, e)

        then:
        // Participation for some reason not saved ):
        shouldFail(EventFullException) {
            service.join(p2, e)
        }
    }

    private def save(domain) {
        domain.save flush: true, failOnError: true
    }

What I see is that the Event and Person domain objects are saved as expected but for the Participation object the (IntelliJ) Debugger displays "unsaved" next to it. This is also the case if I call def part = save(new Participation(p1, e)) directly. So e.getParticipants().size() is 0 when join(...) is called the second time and the error is not thrown.

The whole thing works when I run the application normally and test this manually in the browser.

What am I missing here? Thanks for the help.

Aucun commentaire:

Enregistrer un commentaire