Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring Mockito@InjectMocks是如何工作的?_Spring_Dependency Injection_Mockito_Autowired - Fatal编程技术网

Spring Mockito@InjectMocks是如何工作的?

Spring Mockito@InjectMocks是如何工作的?,spring,dependency-injection,mockito,autowired,Spring,Dependency Injection,Mockito,Autowired,我的问题是: 我有几个web服务类要测试它们是否都从通用服务继承了它们的方法。我想我可以按功能区域(即三组测试方法,每个方法都依赖于不同的底层DAO方法调用)来分解测试套件,而不是为每个方法编写单元测试 我建议做的是: @Mock StateDAO mockedStateDao; @Mock CountyDAO mockedCountyDao; @Mock VisitorDAO mockedVisitorDao; 然后打电话: @InjectMocks CountyServiceImpl<

我的问题是:

我有几个web服务类要测试它们是否都从通用服务继承了它们的方法。我想我可以按功能区域(即三组测试方法,每个方法都依赖于不同的底层DAO方法调用)来分解测试套件,而不是为每个方法编写单元测试

我建议做的是:

@Mock StateDAO mockedStateDao;
@Mock CountyDAO mockedCountyDao;
@Mock VisitorDAO mockedVisitorDao;
然后打电话:

@InjectMocks CountyServiceImpl<County> countyService = new CountyServiceImpl<County>();
@InjectMocks StateServiceImpl<State> stateService = new StateServiceImpl<State>();
@InjectMocks VisitorServiceImpl<Visitor> visitorService = new VisitorServiceImpl<Visitor>();
@InjectMocks CountyServiceImpl countyService=new CountyServiceImpl();
@InjectMocks StateServiceImpl stateService=新的StateServiceImpl();
@InjectMocks VisitorServiceImpl visitorService=新VisitorServiceImpl();
如何确保每个mockedDAO都被注入到正确的服务中? 自动连接这三个选项(而不是使用@InjectMock)会更容易吗


我正在使用Spring、Hibernate和Mockito…

无需担心,在线查看-InjectMocks注释将带有@Mock注释的任何内容视为一个字段,并且是静态范围的(类范围),因此我真的无法保证mocks将转到正确的服务。这在某种程度上是一个试图在特性级别而不是类级别进行单元测试的思想实验。我想我会用Spring自动连接这些东西…

好吧,静态方法用于引导整个过程

我不知道它是如何工作的,因为我还没有浏览过源代码,但我会实现如下内容:

@RunWith (SpringJUnit4ClassRunner.class)
@ContextConfiguration (loader = SpringockitoContextLoader.class, locations =    {"classpath:/org/example/package/applicationContext.xml"})
public class NameOfClassTest {

    @Autowired
    @ReplaceWithMock 
    StateDAO mockedStateDao;

    @Autowired
    @ReplaceWithMock 
    CountyDAO mockedCountyDao;

    @Autowired
    @ReplaceWithMock 
    VisitorDAO mockedVisitorDao;
  • 使用
    @Mock
    注释扫描传递的
    对象的类中的成员变量
  • 对于每个类,创建该类的模拟,并将其设置为该成员
  • 使用
    @InjectMocks
    注释扫描传递的
    对象的类中的成员变量
  • 扫描找到的每个成员的类,查找可以注入(2)中创建的模拟对象之一的成员(即,该字段是父类/接口,或与声明的模拟对象类相同的类),并将其设置为该成员

  • nicholas的答案几乎是正确的,但与其猜测,不如看看的javadoc,它包含了更多的细节;)

    对我来说,在一个测试中有这么多服务是很奇怪的,作为单元测试或集成测试,它感觉不太对。在单元测试中,这是错误的,因为您有太多的协作者,它看起来不像面向对象(或实体)。在集成测试中,这很奇怪,因为使用DB测试集成的代码没有模拟它

    对于1.9.5中的快速参考,您有:

    标记应在其上执行注射的字段

    允许速记模拟和间谍注入。 最大限度地减少重复模拟和间谍注射。 Mockito将尝试仅通过构造函数注入、setter注入或属性注入按顺序注入mock,如下所述。如果以下任何策略失败,Mockito不会报告失败;i、 e.您必须自己提供依赖项

  • 构造函数注入选择最大的构造函数,然后仅使用测试中声明的mock解析参数

    注意:如果找不到参数,则传递null。如果需要不可模仿的类型,那么构造函数注入就不会发生。在这些情况下,您必须自己满足依赖关系

  • 属性设置器注入模拟将首先按类型解析,然后,如果存在多个相同类型的属性,则通过属性名称和模拟名称的匹配来解析

    注1:若您有相同类型(或相同擦除)的属性,最好使用匹配的属性命名所有@Mock注释字段,否则Mockito可能会混淆,不会发生注入

    注意2:如果@InjectMocks实例之前没有初始化,并且没有参数构造函数,那么它将使用此构造函数初始化

  • 场注入模拟将首先按类型解析,然后,如果存在多个相同类型的属性,则通过字段名和模拟名的匹配来解析

    注1:若您有相同类型(或相同擦除)的字段,最好使用匹配字段命名所有@Mock注释字段,否则Mockito可能会混淆,不会发生注入

    注意2:如果@InjectMocks实例之前没有初始化,并且没有参数构造函数,那么它将使用此构造函数初始化


  • 如果您有多个服务,并且希望在基于Spring的环境中用模拟对象替换DAO,我建议您使用Springockito:

    这里也提到了:

    然后,您的Testclass可能如下所示:

    @RunWith (SpringJUnit4ClassRunner.class)
    @ContextConfiguration (loader = SpringockitoContextLoader.class, locations =    {"classpath:/org/example/package/applicationContext.xml"})
    public class NameOfClassTest {
    
        @Autowired
        @ReplaceWithMock 
        StateDAO mockedStateDao;
    
        @Autowired
        @ReplaceWithMock 
        CountyDAO mockedCountyDao;
    
        @Autowired
        @ReplaceWithMock 
        VisitorDAO mockedVisitorDao;
    
    在@Test或@Before方法中,您可以通过标准Mockito方式设置模拟:

    Mockito.doReturn(null).when(mockedCountyDao).selectFromDB();
    

    将在一个测试类中执行此操作。此外,我在Spring test-application-context.xml文件中已经有@injectmock的项(因此我可以自动连接它们)。不确定自动连线和注入模拟之间的区别。编辑原始问题以添加其他内容,而不是对问题留下评论。