Интеграционное тестирование Grails NPE с использованием h2

StackOverflow https://stackoverflow.com//questions/23057439

  •  26-12-2019
  •  | 
  •  

Вопрос

Я пытаюсь написать интеграционный тест в Grails, используя базу данных h2.Я использую h2, поэтому мне не нужно настраивать базу данных на сервере CI.Однако у меня возникли проблемы с инициализацией данных в моей базе данных.

Вот как сейчас выглядит мой тест:

class PathGeneratorServiceSpec extends Specification {

  def pathGeneratorService

  def setup() {
    PathSeed pathSeed = new PathSeed(id:1, seed:0).save()
  }

  void "getNextPath should return a string"() {
    when:
      def retVal = pathGeneratorService.getNextPath()

    then:
      retVal instanceof String
  }
}

Однако, когда я пытаюсь запустить тест, я получаю NPE: Cannot get property 'seed' on null object

Кстати, вот как выглядит мой сервис:

public String getNextPath() {
    def seedValue = getNextSeed()
    def path = createPath(seedValue)
    return path
}

private def getNextSeed() {
    def seedValue
    PathSeed.withTransaction { txn ->
        def seed = PathSeed.lock(1)
        seedValue = seed.seed
        seed.seed++
        seed.save()
    }
    return seedValue
}
Это было полезно?

Решение

Я думаю, что проблема вызвана вашей попыткой присвоить значение столбцу идентификаторов.Если вы замените это:

PathSeed pathSeed = new PathSeed(id:1, seed:0).save()

с

PathSeed pathSeed = new PathSeed(seed:0).save()

а также заменить:

PathSeed.lock(1)

с:

PathSeed.first()

Это решает вашу проблему?Никогда не нужно явно присваивать значение id, и вам следует избегать жесткого кодирования значений идентификатора, например. PathSeed.lock(1)

Обновлять

Вы спросили в комментарии

Есть ли способ сначала заблокировать базу данных?

Нет, но вы можете адаптировать приведенное выше решение для использования пессимистической блокировки следующим образом:

class PathGeneratorServiceSpec extends Specification {

  def pathGeneratorService
  private Long pathSeedId

  def setup() {
    pathSeedId = new PathSeed(seed:0).save().id
  }

  void "getNextPath should return a string"() {
    when:
      def retVal = pathGeneratorService.getNextPath(pathSeedId)

    then:
      retVal instanceof String
  }
}

public String getNextPath(id) {
    def seedValue = getNextSeed(id)
    def path = createPath(seedValue)
    return path
}

private def getNextSeed(id) {
    def seedValue
    PathSeed.withTransaction { txn ->
        def seed = PathSeed.lock(id)
        seedValue = seed.seed
        seed.seed++
        seed.save()
    }
    return seedValue
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top