gpt4 book ai didi

java - 使用 spock 模拟返回链式方法

转载 作者:行者123 更新时间:2023-12-02 11:18:51 29 4
gpt4 key购买 nike

我已经被这个问题困扰了一段时间。是否可以模拟 new URL(url).openStream() 返回 file.gz ?我正在使用 spock 来尝试执行此操作。

public class DownloadFile {
public BufferedReader downloadGzipCsvFile(String url) throws MalformedURLException {
BufferedReader br = null;
if (UrlValidator.getInstance().isValid(url)){
try {
br = new BufferedReader(new InputStreamReader(new GZIPInputStream(new URL(url).openStream())));
} catch (IOException e) {
e.printStackTrace();
System.exit(0);
}
} else{
throw new MalformedURLException("Supplied URL: " + url + " is an invalid URL");
}
return br;
}
}

测试类

class DownloadFileSpec extends Specification{

def "Should return buffered reader for url for gzip csv file"(){
given:
String url = "http://www.test.com"
DownloadFile downloadFile = new DownloadFile()

when:
BufferedReader br = downloadFile.downloadGzipCsvFile(url)
_.openStream() << new FileInputStream("../../../../resources/test_data.csv.gz")

then:
br.ready()
}
}

或者我最好编写一个返回流的私有(private)方法?

最佳答案

可测试性的问题几乎总是相同的:没有依赖注入(inject)。这个案例也不异常(exception)。这里的具体问题是,您不能简单地提供 file://... URL,因为您使用 Apache Commons Validate,它会为 isValid( 生成 false网址)

解决方案是让您的类能够通过 setter 或附加构造函数注入(inject) UrlValidator。我在示例代码中选择了 setter 方法。如果您不喜欢公共(public) setter ,我什至将 setter 设置为包范围,因此您可以将测试放入与原始类相同的包中(无论如何这是常见的做法)以便访问它。

现在只需在测试期间注入(inject)模拟并愉快地使用文件 URL:

package de.scrum_master.stackoverflow;

import org.apache.commons.validator.routines.UrlValidator;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.zip.GZIPInputStream;

public class DownloadFile {
private UrlValidator urlValidator = UrlValidator.getInstance();

void setUrlValidator(UrlValidator urlValidator) {
this.urlValidator = urlValidator;
}

public BufferedReader downloadGzipCsvFile(String url) throws MalformedURLException {
BufferedReader br = null;
if (urlValidator.isValid(url)) {
try {
br = new BufferedReader(
new InputStreamReader(
new GZIPInputStream(
new URL(url).openStream()
)
)
);
} catch (IOException e) {
e.printStackTrace();
System.exit(0);
}
}
else {
throw new MalformedURLException("Supplied URL: " + url + " is an invalid URL");
}
return br;
}
}
package de.scrum_master.stackoverflow

import org.apache.commons.validator.routines.UrlValidator
import spock.lang.Specification

class DownloadFileSpec extends Specification {
def "Should return buffered reader for url for gzip csv file"() {
given:
String url = new File("src/test/resources/test_data.csv.gz").toURI().toURL()
def downloadFile = new DownloadFile()
downloadFile.urlValidator = Mock(UrlValidator) {
isValid(_) >> true
}

when:
def bufferedReader = downloadFile.downloadGzipCsvFile(url)

then:
bufferedReader.ready()
}
}

顺便说一句,该测试还展示了如何将从相对路径创建的 File 实例转换为文件 URL。

P.S.:您还可以使用 PowerMock 来模拟静态方法或构造函数,这也可以解决问题。但我相信,每当你需要 PowerMock 时,它都是一种代码味道,你应该重构,这就是我为你所做的。

关于java - 使用 spock 模拟返回链式方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50077886/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com