JUnit / Spring / Mockito - 无法从另一个实现ApplicationContextAware的类返回的mock类

时间:2014-08-14 21:19:33

标签: java spring unit-testing junit mockito

我是Spring和JUnit的新手。我需要模拟一个派生自ApplicationContextAware类的类,该类位于我的toBeTested(getList)方法中。在下面的短代码片段中,我需要在abc类中测试getList方法。

我可以模拟ModulesConfigRegistry,因为它有一个setter。但我无法模拟ModuleConfig和ListProvider。 ModulesConfigRegistry和ModuleConfig都实现了ApplicationContextAware,因此它从bean返回类。 ListProvider.getList(代码中的lst.getList)是进一步调用数据库的方法,需要进行模拟。提前感谢您的帮助。代码示例将非常有用,因为我是Spring和JUnit的新手。

class abc { 

    private ModulesConfigRegistry modulesConfigRegistry; 

    public void setModulesConfigRegistry(ModulesConfigRegistry modulesConfigRegistry) { 
        this.modulesConfigRegistry = modulesConfigRegistry; 
    } 

    public List getList(String name, String moduleName) 
    { 
        ModuleConfig moduleConfig = modulesConfigRegistry.getModuleConfig(moduleName); 
        Object mlist = moduleConfig.getListProvider(name); 
        if(mlist instanceof ListProvider) 
        { 
            ListProvider lst = (ListProvider)mList; 
        } 
        return lst.getList("abc"); 
    } 
}

2 个答案:

答案 0 :(得分:0)

也许还有另一种更简单的方法来实现这一目标(不是强制性的最好的)。根据我的经验,我在单元测试时使用了Reflection in Java。毕竟,对我而言,单元测试的主要目的是简单地运行最小的可测试部分,仅此而已。这就是为什么我只需要使用我的虚拟测试对象并获取/设置我需要的字段/属性。

但是,这里必须考虑的一件事是反射允许代码执行在非反射代码中非法的操作,例如访问私有字段和方法,使用反射会导致意外的副作用。所以,如果你知道你做了什么,这是一个很好的选择。

由于您已经使用

  

JUnit的

Java中一个非常常见的用例是带注释的用法。例如,JUnit 4将使用反射来查看使用@Test注释标记的方法的类,然后在运行单元测试时调用它们。

如果您想考虑并使用它 - 在这里您可以找到some good examples

干杯。

答案 1 :(得分:0)

此处的一种方法是为需要与ModuleConfigListProvider进行交互的每个对象创建模拟对象

@RunWith(MockitoJUnitRunner.class)
public class abcTest{

    @InjectMocks
    private abc abcInstance;

    @Mock
    private ModulesConfigRegistry modulesConfigRegistry ;

    @Test
    private voidTestGetList(){
    //Create the mock and interactions
    ModuleConfig moduleConfigMock = Mockito.mock(ModuleConfig.class);
    ListProvider listProviderMock =  Mockito.mock(ListProvider.class);
    ArrayList listToReturn = new ArrayList();
    Mockito.when(modulesConfigRegistry.getModuleConfig(Mockito.anyString())).thenReturn(moduleConfigMock);
    Mockito.when(moduleConfigMock.getListProvider(Mockito.anyString())).thenReturn(listProviderMock);
    Mockito.when(listProviderMock.getList(Mockito.anyString())).thenReturn(listProviderMock);
    //Call real method
    List resultList = abcInstance.getList("stringInput1", "stringInput2");
    //Make assertions
    } 
}

基本上,您需要为从模拟对象获得的任何实例创建模拟对象,并使用mockito来定义其方法的结果。

其他选项是创建一个实现或者是返回的对象类型的子类的新类,并覆盖这些方法。