У меня есть следующий код Spring для тестирования с помощью Spock:
@Service
@RequiredArgsConstructor
public class MyService {
private final RestTemplateBuilder restTemplateBuilder;
// ...
public Path downloadFile(String url) {
try {
ResponseEntity<byte[]> response = buildRestTemplate().getForEntity(url, byte[].class);
File tempFileZip = File.createTempFile("myTempFile", ".zip");
FileUtils.writeByteArrayToFile(tempFileZip, response.getBody());
return tempFileZip.toPath();
} catch (Exception e) {
// ...
}
}
private RestTemplate buildRestTemplate() {
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
Proxy proxy = new Proxy(/*...*/);
requestFactory.setProxy(proxy);
return restTemplateBuilder.requestFactory(() -> requestFactory).build();
}
}
В этом коде загружается файл. У меня есть пример файла в моей папке test / resources, который я хочу передать в результате тупой загрузки. Это один из способов заставить его работать, и у меня есть несколько вопросов по этому поводу:
package de.scrum_master.stackoverflow.q59630155
class MySpec extends Specification {
RestTemplate restTemplate = Stub {
getForEntity(_, byte[].class) >>
ResponseEntity.ok(
Files.readAllBytes(
Paths.get(
getClass()
.getResource("/data/MySample/MySample.zip")
.toURI()
)
)
)
}
RestTemplateBuilder restTemplateBuilder = Stub()
def myService = new MyService(restTemplateBuilder)
def setup() {
with(restTemplateBuilder) {
requestFactory(_) >> restTemplateBuilder
build() >> restTemplate
}
}
def "downloadFile"() {
when:
def response = myService.downloadFile()
then:
// ...
cleanup:
Files.delete(response)
}
}
A) Я хотел бы лучше понять, почему путь файла ресурсов оценивается через отладчик для ... target / test-classes / data / ebaRegistrySample / ebaRegistrySample.zip вместо чего-то, содержащего / test / resources Это из-за maven?
РЕДАКТИРОВАТЬ: В комментариях было дано ответ, что это из-за maven inded.
B) Заглушка RestTemplateBuilder в setup () или в тесте работает нормально. Также работает заглушка RestTemplate там или при инициализации в spe c, как показано, также работает. Но когда я также заглушаю RestTemplateBuilder при инициализации в spe c:
package de.scrum_master.stackoverflow.q59630155
class MySpec extends Specification {
// ...
RestTemplateBuilder restTemplateBuilder = Stub {
requestFactory(_) >> restTemplateBuilder
build() >> restTemplate
}
// ...
}
, я получаю
java.lang.NullPointerException: null
Я получаю то же исключение, когда я
build() >> null
Я подозреваю, что заглушка restTemplate и restTemplateBuilder при инициализации в Spe c приводит к тому, что restTamplate еще не имеет значения, когда restTemplateBuilder пытается получить к нему доступ. Кажется, что цепочка заглушек при инициализации должна работать, так что это может быть ошибкой.
Это ошибка или есть другая причина, почему она не работает?
РЕДАКТИРОВАТЬ: Это работает, когда я заглушаю метод requestFactory отдельно после инициализации. Так что это просто другая ошибка в случае C.
C) Заготовка RestTemplateBuilder при его инициализации не работает вообще. В то время как предыдущий случай приводит к исключению, размещение его в setup () или в тесте:
package de.scrum_master.stackoverflow.q59630155
class MySpec extends Specification {
def "downloadFile"() {
setup:
RestTemplate restTemplate = Stub {
getForEntity(_, byte[].class) >>
ResponseEntity.ok(
Files.readAllBytes(
Paths.get(
getClass()
.getResource("/data/MySample/MySample.zip")
.toURI()
)
)
)
}
RestTemplateBuilder restTemplateBuilder = Stub() {
requestFactory(_) >> restTemplateBuilder
build() >> restTemplate
}
def myService = new MyService(restTemplateBuilder)
// ...
}
}
фактически приводит к ошибке компиляции:
requestFactory(_) >> restTemplateBuilder
No candidates found for method call restTemplateBuilder
РЕДАКТИРОВАТЬ: A Коллега предполагает, что это на самом деле предназначено, потому что оно защищает от неопределенного рекурсивного выделения памяти в стеке.
Это ошибка или есть другая причина, почему она не работает?