Java 从构造函数中初始化实例变量时出现Mockito错误
我正在使用Mockito为spring应用程序编写单元测试,下面是服务类的单元测试 服务类别:Java 从构造函数中初始化实例变量时出现Mockito错误,java,spring,unit-testing,mockito,Java,Spring,Unit Testing,Mockito,我正在使用Mockito为spring应用程序编写单元测试,下面是服务类的单元测试 服务类别: @Service class MyServiceImpl implements MyService{ @Autowired private ExternalService externalService; MyServiceImpl () { int value = externalService.getValues(); } } 正如您所注意到
@Service
class MyServiceImpl implements MyService{
@Autowired
private ExternalService externalService;
MyServiceImpl () {
int value = externalService.getValues();
}
}
正如您所注意到的,我使用一个名为ExternalService的服务类中的方法初始化构造函数中的一个实例变量,该服务类是自动连接的
测试等级:
public class LotteryServiceImplTest {
@InjectMocks
private MyServiceImpl myService;
@Mock
private ExternalService externalService;
@Before
public void init() {
MockitoAnnotations.initMocks(this);
}
@Test
public void testGetLotteryResult() {
//test specific code
}
}
当我运行测试时,它会给出一个错误:
org.mockito.exceptions.base.MockitoException:
Cannot instantiate @InjectMocks field named 'value' of type 'MyServiceImpl'.
You haven't provided the instance at field declaration so I tried to construct the instance.
However the constructor or the initialization block threw an exception : null
当测试对象的构造函数依赖于模拟时,如何在注入测试对象之前创建模拟服务?问题在于在MyServiceImpl类中注入和使用ExternalService依赖关系的方式@Autowired由BeanPostProcessor()处理,该处理器在bean实例化后运行。因此,externalService引用的值仅在构造函数运行后初始化。因此,您不能在构造函数中使用它,因为此时它仍然为null 您可以通过移动此行int value=externalService.getValues()来修复此问题;从构造函数到业务方法 如果您想在启动时初始化一次值,可以使用@PostConstruct初始化回调,如下所示
@Service
class MyServiceImpl implements MyService{
@Autowired
private ExternalService externalService;
private int value;
MyServiceImpl () {
}
@PostConstruct
public void initValue(){
value = externalService.getValues();
}
}
您正在尝试实例化
MyServiceImpl
类,并且在MyServiceImpl
构造函数的下一行中,autowiredexternalService
变量绝对为空
int value = externalService.getValues();
为了让Mockito创建一个mock,它必须根据您的帖子调用no-arg构造函数。因此,结果将是NullPointerException
执行此初始化的最佳位置之一是在@Before
带注释的方法中,在该方法中可以调用externalService.getValues()
并使用setter方法设置值
实例变量