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 将不会尝试其他策略,这就是 redisConnectionConfig
是 null
的原因,因为它必须直接注入 属性 本身.当您注释掉构造函数时,Mockito 将只有 StringCircularQueue
的默认无参数构造函数供其使用。由于这不会注入任何东西,Mockito 会尝试 属性 注入,因此这次你会得到一个非空的 redisConnectionConfig
。您可以在 https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/InjectMocks.html.
的官方文档中阅读更多相关信息
我有一个 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 将不会尝试其他策略,这就是 redisConnectionConfig
是 null
的原因,因为它必须直接注入 属性 本身.当您注释掉构造函数时,Mockito 将只有 StringCircularQueue
的默认无参数构造函数供其使用。由于这不会注入任何东西,Mockito 会尝试 属性 注入,因此这次你会得到一个非空的 redisConnectionConfig
。您可以在 https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/InjectMocks.html.