繁体   English   中英

如何使用 Spock 模拟一个 class 有一个什么都不返回的方法

[英]How to mock a class that has a method that returns nothing, using Spock

我目前正在尝试为我创建的 class 设置 Spock 测试,该测试有一个不返回任何内容的方法。

public final class Test implements ITest {

    private static Logger logger = LoggerFactory.getLogger(test.class);

    private DataSource testSource;

    public Test(DataSource testSource) {
        testSource = testSource;
    }

    public void validateFile() {

        if (logger.isDebugEnabled()) {
            logger.debug("validating file");
        }

        Handler handler = new Handler();
        handler.getValues(testSource);
    }
}

以上是我要 Spock 测试的测试,我只想测试这个 class 而不是具有方法 getValues 的 Handler class。

这是我的模拟测试 class:

def "test buildConfig"() {
    given:
    DataSource testSource = Mock()
    Handler handler = Mock()
    Test test = new Test(testSource)
    when:
    test.validateFile()
    then:
    1 * handler.getValues(_)
}

但是我得到了一个 null 指针异常,因为 handler.getValues 似乎在该方法中做了一些我没有提供的逻辑。 但我不关心 class:我只是想测试当我在测试 class 中运行 validateFile 方法时,它会创建一个处理程序并调用处理程序上的 getValues 方法。

因为您的 class 创建了自己的new Handler() ,所以它没有使用您创建的 Mock。

为了能够验证这一点,您需要重构 class 以使其更易于测试。

传入处理程序

首先,让我们看一下将 Handler 传递给方法:

public final class Test implements ITest {

    private static Logger logger = LoggerFactory.getLogger(test.class);

    private DataSource testSource;

    public Test(DataSource testSource) {
        testSource = testSource;
    }

    public void validateFile(Handler handler) {

        if (logger.isDebugEnabled()) {
            logger.debug("validating file");
        }

        handler.getValues(testSource);
    }
}

现在我们可以将我们的模拟传递到我们的 validateFile 调用中并成功验证它:

def "test buildConfig"() {
    given: 'a datasource, handler and Test'
    DataSource testSource = Mock()
    Handler handler = Mock()
    Test test = new Test(testSource)

    when: 'we validate our file'
    test.validateFile(handler)

    then: 'our handler was invoked'
    1 * handler.getValues(_)
}

使用供应商

如果我们真的希望在方法内部创建 Handler,那么我们可以按照@leonard-brünings 的评论传入Supplier<Handler>

作为更改 verifyFile() 签名的替代方法,这一次,让我们重写我们的构造函数以将 Supplier 作为参数并将我们的 function 存储为一个字段:

public final class Test implements ITest {

    private static Logger logger = LoggerFactory.getLogger(test.class);

    private DataSource testSource;
    private Supplier<Handler> supplierOfHandler;

    public Test(DataSource testSource, Supplier<Handler> handlerSupplier) 
    {
        testSource = testSource;
        supplierOfHandler = handlerSupplier;
    }

    public void validateFile() {

        if (logger.isDebugEnabled()) {
            logger.debug("validating file");
        }
        handler = supplierOfHandler.get()
        handler.getValues(testSource);
    }
}

...然后与返回 Mock Handler 的供应商一起设置我们的测试,然后我们可以使用它来验证交互:

def "test buildConfig"() {
    given: 'a datasource, handler and Test'
    DataSource testSource = Mock()
    Handler handler = Mock()
    Test test = new Test(testSource, () -> handler)

    when: 'we validate our file'
    test.validateFile()

    then: 'our handler was invoked'
    1 * handler.getValues(_)
}

暂无
暂无

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

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