Micronaut: внедрение списка значений с @Property в тестовый класс не работает должным образом - PullRequest
2 голосов
/ 29 октября 2019

Как определить определенное свойство для тестирования, которое представляет собой список, а не просто строку?

Документация объясняет, как делать со строкой , но я не могу установитьvalue к списку строк.

application.yml

items:
  - "Item 1"
  - "Item 2"

Тестовый файл:

@MicronautTest(environments = ["test"])
class MyTest {

    @Test
    @Property(name = "items", value = "Item 1,Item 2") // this does not work
    fun justWithOneItem() {
        // ...
    }
}

О фактическом коде, это работает ( как описано здесь )

Файл проекта:

@Singleton
class SomeClass {
    @set:Inject
    @setparam:Property(name = "items")
    var items: List<String>? = null

    // ...
}

Я знаю, что могу создать application-test.yml и сделать

@MicronautTest(environments = ["test"])
class MyTest {
    // ...
}

Но я бы предпочел установить его программно, а не создавать новый файл env / yaml.

Ответы [ 2 ]

1 голос
/ 30 октября 2019

Я думаю, у вас есть 2 варианта:

  1. Использование @Property(name = "items[0]", value = "Item1") и @Property(name = "items[1]", value = "Item2")

  2. Измените свой тест на реализацию TestPropertyProviderи предоставьте конфиг через возвращенную карту

1 голос
/ 30 октября 2019

Добавление @Property в такой тестовый метод будет работать, если вы добавите список items в свой тестовый класс. Примерно так: (я знаю, что это тест Спока, а не Котлина, но вы должны понять это.)

package com.github.wololock.micronaut.products

import io.micronaut.context.annotation.Property
import io.micronaut.test.annotation.MicronautTest
import spock.lang.Specification

@MicronautTest(environments = ["test"])
class MyTest extends Specification {

    @Property(name = "items")
    List<String> items

    def "should use default items"() {
        expect:
        items == ["Item 1", "Item 2"]
    }

    @Property(name = "items", value = "Item 3,Item 4,Item 5")
    def "should override default items"() {
        expect:
        items == ["Item 3", "Item 4", "Item 5"]
    }
}

Однако вы используете бин SomeClass, которыйиспользует введенные предметы. Дело в том, что когда вы вводите объект someClass в ваш тестовый класс, бин уже создан и он неизменен. Вот почему добавление @Property в одном из методов тестирования не приведет к реконструкции объекта bean.

package com.github.wololock.micronaut.products

import io.micronaut.context.annotation.Property
import io.micronaut.test.annotation.MicronautTest
import spock.lang.Specification

import javax.inject.Inject

@MicronautTest(environments = ["test"])
class MyTest extends Specification {

    @Inject
    SomeClass someClass

    def "should use default items"() {
        expect:
        someClass.items == ["Item 1", "Item 2"]
    }

    @Property(name = "items", value = "Item 3,Item 4,Item 5")
    def "should override default items"() {
        expect:
        someClass.items == ["Item 3", "Item 4", "Item 5"]
    }
}

Вывод:

enter image description here

К счастью, есть решение этой проблемы. Вы можете использовать @MockBean для доставки реализации SomeClass объекта. В этом случае вы можете определить метод, который ожидает параметр @Property(name="items") List<String> items, добавив, таким образом, аннотацию @Property поверх тестового метода, чтобы переопределить значения, переданные методу, аннотированному @MockBean:

package com.github.wololock.micronaut.products

import io.micronaut.context.annotation.Property
import io.micronaut.test.annotation.MicronautTest
import io.micronaut.test.annotation.MockBean
import spock.lang.Specification

import javax.inject.Inject

@MicronautTest(environments = ["test"])
class MyTest extends Specification {

    @Inject
    SomeClass someClass

    def "should use default items"() {
        expect:
        someClass.items == ["Item 1", "Item 2"]
    }

    @Property(name = "items", value = "Item 3,Item 4,Item 5")
    def "should override default items"() {
        expect:
        someClass.items == ["Item 3", "Item 4", "Item 5"]
    }

    @MockBean(SomeClass)
    SomeClass someClassMock(@Property(name = "items") List<String> items) {
        return new SomeClass(items)
    }
}

Output:

enter image description here

Я использовал тесты Java и Spock Framework (Groovy) в моих примерах, но вы должны быть в состоянии достичь того же с Kotlin. Надеюсь, это поможет.

...