Jmockit解决@Qualifier和@Resource出现 Missing @Injectable报错

当使用Jmockit进行单元测试时,如果代码中包含@Qualifier和@Resource注解来注入对象,可能会遇到缺少@Injectable的错误。本文通过一个具体的例子展示了如何在测试案例中配置@Injectable,以匹配@Resource(name=newOrderServiceImpl)或@Qualifier(newOrderServiceImpl),确保测试的正确运行。解决方案是确保测试类中的变量名与注解中的值一致。

Jmockit模拟@Qualifier和@Resource注入对象

开发的代码中有时会使用@Qualifier配合着@Autowired一起使用, 或者是使用@Resource来注入对象, 当Jmockit中使用@Injectable来修饰被测试代码依赖的类时, 会出现如下报错信息:

java.lang.IllegalStateException: Missing @Injectable for field "xxx.xxx.xxx.xxxxx.service.OrderService orderService" in UserServiceImpl

业务代码:


/**
 * OrderService有两个实现类,分别为:OrderServiceImpl和NewOrderServiceImpl
 */
@Resource(name = "newOrderServiceImpl")
private OrderService orderService;

@Override
public void useOrderService() {
    String orderId = orderService.getOrderId();
    System.out.println(orderId);
}

OrderServiceImpl

@Service
public class OrderServiceImpl implements OrderService {
    @Override
    public String getOrderId() {
        return "orderServiceId";
    }
} 

NewOrderServiceImpl

@Service
public class NewOrderServiceImpl implements OrderService {
    @Override
    public String getOrderId() {
        return "newOrderId";
    }
}

解决上述报错的测试案例:

/**
 * OrderService变量名newOrderServiceImpl要跟@Resource(name = "newOrderServiceImpl")中保持一致
 */
@Injectable
private OrderService newOrderServiceImpl;
@Tested
private UserServiceImpl userServiceImpl;

@Test
public void testUserOrderService() {
    userServiceImpl.useOrderService();
}

业务代码2:

/**
 * 注入时使用了@Qualifier
 */
@Autowired
@Qualifier("newOrderServiceImpl")
private OrderService orderService;

@Override
public void useOrderService() {
    String orderId = orderService.getOrderId();
    System.out.println(orderId);
}

解决方案与上述测试案例相同, 保持测试案例中的变量名与@Qualifier(“newOrderServiceImpl”)中的值一致

在使用 `@Qualifier` 注解时遇到报错 `The annotation @Qualifier is disallowed for this location`,通常是因为注解的使用位置不符合 Spring 框架的要求,或者与其他工具(如 Lombok)存在兼容性问题。以下是可能的原因分析解决方案: ### 1. **注解使用位置错误** `@Qualifier` 主要用于注入 Bean 的字段、构造函数参数或方法参数上。如果将其用在了不支持的位置,例如类级别或某些非注入上下文中,就会导致该错误。 - **解决方案**: 确保 `@Qualifier` 仅用于以下场景: - 字段注入 ```java @Autowired @Qualifier("beanName") private MyService myService; ``` - 构造函数参数注入 ```java @Autowired public MyClass(@Qualifier("beanName") MyService myService) { this.myService = myService; } ``` - 方法参数注入(如 Setter 方法) ```java @Autowired public void setMyService(@Qualifier("beanName") MyService myService) { this.myService = myService; } ``` ### 2. **与 Lombok 的 `@RequiredArgsConstructor` 冲突** 当使用 Lombok 的 `@RequiredArgsConstructor` 自动生成构造函数时,`@Qualifier` 可能会失效,因为 Lombok 生成的构造函数不会保留注解信息。 - **解决方案**: 需要在 Lombok 的配置文件 `lombok.config` 中添加以下内容,以确保 `@Qualifier` 被正确复制到生成的代码中: ```properties lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Qualifier ``` 这样可以保证 Lombok 在生成构造函数时保留 `@Qualifier` 注解信息[^2]。 ### 3. **多个实现类导致的冲突** 当一个接口有多个实现类时,Spring 容器无法确定应该注入哪一个 Bean,此时需要结合 `@Qualifier` 明确指定 Bean 名称。 - **解决方案**: 在定义 Bean 时为每个实现类指定唯一的名称,并在注入时使用 `@Qualifier` 指定该名称。 ```java @Service("testServiceImplA") public class TestServiceImplA implements TestService { // 实现逻辑 } @Service("testServiceImplB") public class TestServiceImplB implements TestService { // 实现逻辑 } ``` 在注入时: ```java @Autowired @Qualifier("testServiceImplA") private TestService testService; ``` 如果不想使用 `@Qualifier` 或 `@Primary`,还可以通过自定义限定符注解来区分不同的实现类[^3]。 ### 4. **未启用组件扫描或 Bean 未注册** 如果 Spring 容器没有正确扫描到目标 Bean 或者 Bean 没有被注册,也会导致注入失败。 - **解决方案**: 确保目标 Bean 所在的包位于组件扫描路径下,并且使用了 `@Component`、`@Service` 或 `@Repository` 等注解进行标注。 ### 5. **依赖版本问题** 某些旧版本的 Spring 框架可能对 `@Qualifier` 的支持不够完善,或者与其他库存在兼容性问题。 - **解决方案**: 升级 Spring Boot 到最新稳定版本,确保框架本身对注解的支持是完整的。 ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值