Тест интеграции Spring Boot с помощью Spock: метод stubbed возвращает ноль - PullRequest
1 голос
/ 23 января 2020

Я создаю java приложение для Raspberry Pi с использованием Pi4j.

Приложению не удается запустить операционную систему из-за отсутствия драйверов GPIO. Вот почему, когда я запускаю свои тесты интеграции спока, мне нужно смоделировать / заглушить бин, основанный на оригинальном API Pi4j. Моя проблема заключается в том, что сам bean-компонент является поддельным, но метод-заглушка возвращает нулевое значение вместо значения, которое я определяю.

@SpringBootTest
class RoboApplicationTest extends Specification {

    @Autowired
    ApplicationContext context

    @SpringBean
    GpioController gpioController = Stub()

    def "test context loads"() {
        given:
        gpioController.provisionDigitalInputPin(_, _, _) >> { throw new RuntimeException("I'm stubbed!") }

        expect:
        context != null
        context.containsBean('gpioController')
    }
}

Вместо того, чтобы выдавать исключение или возвращать что-либо, что я положил туда, метод «provisionDigitalInputPin» возвращает нулевое значение, которое вызывает далее NPE.

Вы можете найти все приложение здесь: https://github.com/ahlinist/raspberry-pi4j/tree/feature/integration-tests

Я пытаюсь добиться результата, описанного здесь: https://github.com/spockframework/spock/blob/master/spock-spring/boot-test/src/test/groovy/org/spockframework/boot/SpringBeanIntegrationSpec.groovy

Я пробовал много подходов без результата. Подобный тест с Mockito работает хорошо. Чего мне не хватает?

Обновление: Для запуска интеграционных тестов выполните:

./gradlew integrationTest

Обновление 2: Соответствующий билет Спока # 1084 создано на GitHub.

1 Ответ

0 голосов
/ 24 января 2020

Когда я клонирую ваш проект и запускаю тест, я также вижу NPE, ...

java.lang.IllegalStateException: Failed to execute ApplicationRunner
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:778) ~[spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
    (...)
Caused by: java.lang.NullPointerException: null
    at robot.controller.impl.RaspberryPiInputImpl.addListener(RaspberryPiInputImpl.java:19) ~[main/:na]
    at robot.sensor.AbstractSensor.init(AbstractSensor.java:21) ~[main/:na]
    at robot.TwoWheelRobot.init(TwoWheelRobot.java:20) ~[main/:na]
    at robot.RoboApplication.run(RoboApplication.java:26) ~[main/:na]
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:775) ~[spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
    ... 61 common frames omitted

... но не в вашем тесте, а в этого класса :

package robot.controller.impl;

import com.pi4j.io.gpio.GpioPinDigitalInput;
import com.pi4j.io.gpio.event.GpioPinListenerDigital;
import lombok.RequiredArgsConstructor;
import robot.controller.Input;
import robot.controller.Listener;

@RequiredArgsConstructor
public class RaspberryPiInputImpl implements Input {

    private final GpioPinDigitalInput gpioPinDigitalInput;

    @Override
    public void addListener(Listener listener) {
        GpioPinListenerDigital gpioListener = (GpioPinListenerDigital) listener;
        gpioPinDigitalInput.addListener(gpioListener);
    }
}

У вас есть последнее поле GpioPinDigitalInput, которое никогда не инициализируется, т.е. оно всегда будет null. Так что же еще, кроме NPE, вы ожидаете при вызове addListener(..)? Возможно, вам следует ввести туда значение ...

Кроме того, мне пришлось перенести тест с src /gration-test на src / test , иначе Gradle будет не запускайте его, и IntelliJ IDEA также не распознает его как тестовый класс.

...