【问题标题】:Micronaut MockBean/Replaces not working for pojo in controller test using @MicronautTest使用@MicronautTest 在控制器测试中,Micronaut MockBean/Replaces 不适用于 pojo
【发布时间】:2021-09-29 10:35:30
【问题描述】:

我正在使用 Micronaut 框架。我正在为以下控制器编写junit。 -

class Controller {
    Client client;

    List<Object> handleEvent(Object event) {
        try {
            client.handle(event);
        } catch (Exception E) {
            throw new Exception()
        }
    }

}

我想模拟客户端对象。我尝试了@MockBean 注释和@Replaces 注释。但没有运气。

客户端是从工厂注入的 -

@Factory
class ClientFactory {
    @Singleton
    @Named("client_name")
    Client getClient() {
        return new Client();
    }
}

我在测试中尝试了以下注释-

@Inject 
Client client;

@MockBean(bean = Client.class, named = "client_name")
Client getClient() {
    return Mockito.mock(Client.class);
}

它给出错误 - “无法为类注册器的参数 client_name 注入值。给定的限定符 @Named(client_name) 不存在类型的 bean” 注册器是另一个也注入了客户端的类同名。不知道为什么它会进入控制器的画面。

我对这些错误有点困惑。我也试过@Replaces注解,像这样-

@Replaces(value = Client.class, named = "client_name)
Client getClient() {
    return Mockito.mock(Client.class);
}

但没有运气。有人可以指导我在这里缺少什么吗?

【问题讨论】:

    标签: junit5 micronaut


    【解决方案1】:

    您的 Factory 实现表明您的 bean 定义是实际注入的类 new Client()

    Micronaut 无法替换/注入类定义的 bean,您将不得不引入一个中间接口,提供您的 bean 公开 API,然后模拟后者:

    定义你的通用类型接口:

    interface Client {
    
        void handleEvent(Object event);
    
    }
    

    提供默认的Client 实现(请注意,您可以为工厂提供程序提供Primary 注释,以便在存在多种可注入类型时将其选为默认值):

    public class DefaultClient {
    
        public void handleEvent(Object event) {
            // your default implementation goes here
        }
    
    }
    

    你的Factory 应该注入默认的具体实现:

    @Factory
    public class ClientFactory {
        
        @Singleton
        @Named("client_name")
        public Client getClient() {
            return new DefaultClient();
        }
    }
    

    您的控制器实现保持不变,不必关心实现细节:

    class Controller {
    
        Client client; // the interface is injected in here
    
        List<Object> handleEvent(Object event) {
            try {
                client.handle(event);
            } catch (Exception E) {
                throw new Exception()
            }
        }
    
    }
    

    然后您的测试 bean 可以让自定义实现替换默认实现:

    @MockBean(DefaultClient.class)
    Client client() {
        return Mockito.mock(Client.class);
    }
    

    作为一般建议,您应该更好地对接口进行编程,并且只在为 bean 自省注解具体实现时注入这些接口。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-20
      • 1970-01-01
      • 2021-06-14
      • 1970-01-01
      相关资源
      最近更新 更多