Spring Junit 测试中模拟的 class 变量显示 Null

Mocked class variable in a Spring Junit test showing Null

我有一个 Spring @Service@Scope("prototype") class 命名为 StringCircularQueue,它有一个构造函数,其中正在初始化名为 queueName 的变量和方法 addElement,如下所示。为了在 class 中对这个方法进行单元测试,我使用 JUnit Mockito 来模拟 RedisConnectionConfig,它在 addElement 方法中使用.

调试测试时,addElement方法中的redisConnectionConfig变量显示为null。但是,如果我注释掉构造函数和 运行 一样,redisConnectionConfig 变量显示一个 Non Null 值。

无法弄清楚使用构造函数时出现了什么问题。任何建议都会有很大帮助。

@Service
@Scope("prototype")
public class StringCircularQueue {

    @Autowired
    private RedisConnectionConfig redisConnectionConfig;

    private String queueName;

    public StringCircularQueue(String queueName) {
        this.queueName = queueName;
    }
    
    public Boolean addElement(String element) {
      RedissonClient redisClient = redisConnectionConfig.getRedisClient();
      // Some other business logic
    }
} 
public class RedisCircularQueueTest {
    @InjectMocks
    RedisStringCircularQueue redisStringCircularQueue;
    
    @Mock
    private RedisConnectionConfig redisConnectionConfig;

    @Mock
    private RedissonClient redissonClient;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }
    
    @Test
    public void testAddElementToQueue() {
      Mockito.when(redisConnectionConfig.getRedisClient()).thenReturn(redissonClient);
      Boolean isAdded = redisStringCircularQueue.addElement("testString");
      Assert.assertEquals(true, isAdded);
   }
}

不要依赖字段注入,而是在 StringCircularQueue 中依赖构造函数注入,如下所示:

@Service
@Scope("prototype")
public class StringCircularQueue {

    private RedisConnectionConfig redisConnectionConfig;

    private String queueName;

    public StringCircularQueue(RedisConnectionConfig redisConnectionConfig, String queueName) {
        this.redisConnectionConfig = redisConnectionConfig;
        this.queueName = queueName;
    }
    
    public Boolean addElement(String element) {
      RedissonClient redisClient = redisConnectionConfig.getRedisClient();
      // Some other business logic
    }
} 

有了这个,你的测试就成功了。

当您拥有构造函数时它是 null 的原因如下:Mockito 将尝试仅通过构造函数注入、属性 注入或 setter 注入来注入模拟这个命令。如果使用构造函数成功创建了对象,那么 Mockito 将不会尝试其他策略,这就是 redisConnectionConfignull 的原因,因为它必须直接注入 属性 本身.当您注释掉构造函数时,Mockito 将只有 StringCircularQueue 的默认无参数构造函数供其使用。由于这不会注入任何东西,Mockito 会尝试 属性 注入,因此这次你会得到一个非空的 redisConnectionConfig。您可以在 https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/InjectMocks.html.

的官方文档中阅读更多相关信息