繁体   English   中英

与 Spock 的 Spring Boot 集成测试:存根方法返回 null

[英]Spring Boot integration test with Spock: stubbed method returns null

我正在使用 Pi4j 为树莓派创建一个 Java 应用程序。

由于缺少 GPIO 驱动程序,应用程序无法运行 raspbian 操作系统。 这就是为什么当我运行我的 spock 集成测试时,我需要模拟/存根一个依赖于原始 Pi4j API 的 bean。 我的问题是 bean 本身被模拟了,但是存根方法返回 null 而不是我定义的值。

@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”方法返回 null,这会导致进一步的 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:相应的Spock 票证#1084已在 GitHub 上创建。

当我克隆你的项目并运行测试时,我还看到了一个 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 那么在调用addListener(..)时,除了 NPE,您还期望什么? 也许你应该在那里注入一个价值......

此外,我必须将测试从src/integration-test移动到src/test ,否则 Gradle 不会运行它,IntelliJ IDEA 也不会将其识别为测试类。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM