【发布时间】:2021-08-11 10:47:03
【问题描述】:
我将使用 Micronaut 文档中的代码(声明式 Http 客户端)- 我正在使用 Spock
PetOperations.java
@Validated
public interface PetOperations {
@Post
Single<Pet> save(@NotBlank String name, @Min(1L) int age);
}
我有一个声明式客户端:
@Client("/pets")
public interface PetClient extends PetOperations {
@Override
Single<Pet> save(String name, int age);
}
我的目标是,当我运行一个测试类时,我想调用 (@Replaces) 另一个类 (PetDummy) 而不是 PetClient ,PetDummy 类位于我的测试文件夹中
@Primary
@Replaces(PetClient.class)
@Singleton
public class PetDummy implements PetOperations {
@Override
public Single<Pet> save(String name, int age) {
Pet pet = new Pet();
pet.setName(name);
pet.setAge(age);
// save to database or something
return Single.just(pet);
}
}
测试类:
class PetTest extends Specification {
@Shared
@AutoCleanup
ApplicationContext applicationContext = ApplicationContext.run();
//EmbeddedServer server = applicationContext.getBean(EmbeddedServer.class).start();
PetClient client = applicationContext.getBean(PetOperations.class);
def 'test' (){
given: 'name and age'
when:
client.save("Hoppie", 1);
then:
noExceptionThrown()
}
}
但是,最后调用 PetClient,我也尝试过使用 @Factory 注释,但没有成功
PetClient extends PetOperations 和 PetDummy implements PetOperations,如果它们都实现了,那么使用 @Replaces 会很有意义 ...
还有什么我可以尝试的吗?
谢谢!
另一个问题:
现在它可以工作了,PetClient 是我 PetService 中的一个依赖项。当我测试我的 PetService 时,它仍然调用 PetClient 而不是 PetDummy。
我假设它与 applicationContext 有关,你会看到
宠物服务:
PetService {
@Inject
PetClient client;
buyFood(){
//...
Single<Pet> pet = client.save("Hoppie", 1));
}
}
PerService 测试:
class PetServiceTest extends ApplicationContextSpecification {
@Subject
@Shared
PetService petService = applicationContext.getBean(PetService)
PetOperations client = applicationContext.getBean(PetOperations.class) //client is not used here
def 'test' (){
given:
when:
petService.buyFood()
then:
noExceptionThrown()
}
}
我认为我需要从 PetService 中“进入”applicationContext,告诉“使用 PetDummy”实现(在测试类内部,因为 ApplicationContextSpecification 属于另一个模块
ApplicationContextSpecification 是:
abstract class ApplicationContextSpecification extends Specification implements ConfigurationFixture {
@AutoCleanup
@Shared
ApplicationContext applicationContext = ApplicationContext.run(configuration)
/* def cleanup() {
assert !hasLeakage()
}*/
}
ConfigurationFixture 包含数据库的属性(休眠)
【问题讨论】: