Недопустимые объекты в памяти после неудачной проверки ограничений - PullRequest
0 голосов
/ 15 февраля 2012

Используя Grails 2.0.0, я создал сервис, который создает экземпляры класса Player и сохраняет его в базе данных. Затем я написал интеграционный тест JUnit, который проверяет, что метод службы createNewPlayer (String platformID) выдает исключение, если в Player.save не удалось выполнить проверку ограничения (failOnError: true).

Все идет хорошо, но после метода shouldFail (...), если я вызываю:

assert Player.list().size() == 1;

Я получаю эту ошибку:

--Output from testCreatingNewPlayerWithExistingID--
| Error 2012-02-15 21:52:05,293 [main] ERROR hibernate.AssertionFailure  - an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session)
Message: null id in test1.Player entry (don't flush the Session after an exception occurs)

У меня вопрос: как проверить выбрасывание исключений внутри метода shouldFail, чтобы Hibernate не сохранял в памяти недопустимые экземпляры классов Player с нулевыми идентификаторами после этого?

Ниже приведены примеры кода:

class WorkingService
{
    Player createNewPlayer(String platformID) throws ValidationException {
        Player player = new Player(platformID: platformID);
        return player.save(failOnError : true);
    }
}


class Player
{
    String platformID
    static constraints = {
        platformID nullable: false, blank: false, unique: true
    }
}


@TestFor(WorkingService)
class WorkingServiceTests
{
    WorkingService workingService;

    void testCreatingNewPlayerWithExistingID()
    {
        def player = new Player(platformID: "1");
        player.save(flush: true);

        assert Player.list().size() == 1;

        shouldFail ValidationException, {
            player = workingService.createNewPlayer("1");
        }

        assert Player.list().size() == 1;
    }
}

1 Ответ

1 голос
/ 16 февраля 2012

Я думаю, что проблема в том, что вы смешиваете интеграционные и модульные тесты.Интеграционный тест должен расширять GroovyTestCase и не использовать аннотации преобразования AST, такие как TestFor.Это проходит в моем тестовом приложении:

import grails.validation.ValidationException

class WorkingServiceTests extends GroovyTestCase {

   WorkingService workingService

   void testCreatingNewPlayerWithExistingID() {

      new Player(platformID: "1").save(flush: true)

      assert Player.count() == 1

      shouldFail(ValidationException) {
         workingService.createNewPlayer("1")
      }

      assert Player.count() == 1
   }
}

Не связано - вы не должны использовать list().size(), чтобы получить счетчик из базы данных, поскольку он загружает каждый экземпляр просто для получения номера;используйте count() вместо этого.Также nullable: false является значением по умолчанию, поэтому указывать его излишне.

...