Java @InjectMock是否只在类的全局变量中注入mock?

Java @InjectMock是否只在类的全局变量中注入mock?,java,unit-testing,dependency-injection,mockito,junit5,Java,Unit Testing,Dependency Injection,Mockito,Junit5,我尝试进行以下测试: import org.junit.jupiter.api.beforeach; 导入org.junit.jupiter.api.extension.extensedWith; 导入org.mockito.InjectMocks; 导入org.mockito.Mock; 导入org.mockito.MockedStatic; 导入org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.c

我尝试进行以下测试:

import org.junit.jupiter.api.beforeach;
导入org.junit.jupiter.api.extension.extensedWith;
导入org.mockito.InjectMocks;
导入org.mockito.Mock;
导入org.mockito.MockedStatic;
导入org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
公共类测试{
//需要被嘲笑和注射
@嘲弄
私人某某某某某某;
@注射模拟
private SomeClass SomeClass=new SomeClass();
@试验
无效测试(){
when(someDao.retrieveSomeData),然后return(10);
}
}
这是一个简化类,在该类中我要注入的对象被实例化并在方法中使用:

公共类SomeClass{
私有方法(){
SomeDao SomeDao=新的SomeDao();
retrievSomeData();
}
}
但我也可以通过构造函数中的实例化编写类,如下所示:

公共类SomeClass{
SomeDao SomeDao;
公共类(){
someDao=新的someDao();
}
私有方法(){
retrievSomeData();
}
}
结果:
它仍然是调用reals对象
someDao.rerieveSomeData()
的实函数,而不是我的模拟对象!为什么?我很困惑。

@InjectMock
可以通过三种方式注入mock:

  • 构造函数注入:如果您的
    SomeClass
    有一个类型为
    SomeDao
    的构造函数参数,它将作为该参数传递mock
  • Setter注入:如果
    SomeClass
    有一个Setter方法,其参数类型为
    SomeDao
    (例如
    setDao(SomeDao)
    ,或者有多个这样的Setter,但其中一个与mock同名(即
    setSomeDao(SomeDao)
    ),它将使用mock作为参数调用此Setter
  • 字段注入:如果有一个类型为
    SomeDao
    的字段,或者有多个类型为
    SomeDao
    的字段,但有一个字段与您的mock同名(即
    SomeDao
    ),它将使用mock设置此字段

  • 对于您的代码,这意味着您不应该在
    SomeClass
    类中创建
    SomeDao
    的实例,而应该注入它。在您的正常业务代码中,您将在
    SomeClass
    之外创建DAO,并将其传递给构造函数(通常是首选的注入变量)。在您的测试中,mockito会注意执行相同的操作,但是使用mock而不是真实的DAO。

    您总是在SomeClass中创建一个新的SomeDao,而不是将其作为参数传递到构造函数中。因此,您的mock DAO不会被注入。但是当我将对象传递给构造函数时,
    @InjectMocks
    仍然有必要吗?我可以创建在我的测试中创建一个mock并将其传递给构造函数:`SomeClass-SomeClass=new-SomeClass(mockedSomeDao)?啊,我意识到,我可以使用@InjectMocks进行构造函数注入,也可以自己通过被模拟的类,从这个答案中可以看出没有区别:非常感谢@Ericscheefer!你知道了。如果你在许多测试中需要注入多个东西,可以使用InjectMocks。这可以节省你手动进行注入的工作。