【问题标题】:Micronaut @Replaces with declarative ClientMicronaut @Replaces 用声明式客户端
【发布时间】: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 包含数据库的属性(休眠)

【问题讨论】:

    标签: spock micronaut


    【解决方案1】:

    您已经在检索 PetClient bean 实现:

    PetClient client = applicationContext.getBean(PetOperations.class);
    

    如果使用适当的类型调用,它应该提供替换的虚拟 bean 实现:

    PetOperations client = applicationContext.getBean(PetOperations.class);
    

    【讨论】:

    猜你喜欢
    • 2021-09-14
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多