Java Mockito 模拟类返回 Null

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18928153/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 12:35:49  来源:igfitidea点击:

Mockito Mocked Class returns Null

javaunit-testingjunitmockito

提问by Chaos

I am using Mockito to mock a class in my JUnit test class as follows:

我正在使用 Mockito 在我的 JUnit 测试类中模拟一个类,如下所示:

@Before
public void initialize(){
    DescribeHiveTable mockObj = Mockito.mock(DescribeHiveTable.class);
    String tableName = "clslog_assessments";
    String parentDirectoryPath ="src/test/resources/TEST18/RunFiles";
    String[] mockFeaturesArray1 = {"user_id","event_id"};
    ArrayList<String> mockFeaturesList1 = new ArrayList<String> (Arrays.asList(mockFeaturesArray1));
    when(mockObj.describeTable(tableName, parentDirectoryPath)).thenReturn(mockFeaturesList1);

Then I have my Test method, which subsequently calls the describeTablemethod from within. I checked that the arguments: tableNameand parentDirectoryPathwhen describeTableis being called are same as those I have defined in the initalize method.

然后我有我的 Test 方法,它随后describeTable从内部调用该方法。我检查了参数:tableNameparentDirectoryPath何时describeTable被调用与我在 initalize 方法中定义的参数相同。

However, I still get a null return value. I don't understand this behavior. Maybe I'm not using Mockito correctly?

但是,我仍然得到一个空返回值。我不明白这种行为。也许我没有正确使用 Mockito?

EDIT

编辑

My Test method is something like:

我的测试方法是这样的:

@Test
public void testComplexFeaturesExistingRun() {
String[] args = {masterConfigPath, runFilesPath, rootDir};
DriverClass driver = new DriverClass();
driver.main(args);
}

So driver.main calls the describeTable method, whose behavior I'm trying to mock.

所以 driver.main 调用了 describeTable 方法,我试图模拟它的行为。

EDIT 2

编辑 2

My describe hive table class is :

我的描述蜂巢表类是:

public class DescribeHiveTable {

public ArrayList<String> describeTable(String tableName, String parentDirectoryPath){
    String hiveQuery = "'describe " + tableName + "';";
    String bashScriptFile = parentDirectoryPath + "/describeTable.sh";

    .
    .
    .
        final Process process = builder.start();
        InputStream is = process.getInputStream();
        InputStreamReader isr = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(isr);
        String line;
        while((line=br.readLine())!=null) {
            String[] output = line.split("\t");
            columnList.add(output[0]);
       }
       return columnList;

This is how I'm calling describe table:

这就是我调用描述表的方式:

DescribeHiveTable describeTable;
describeTable = new DescribeHiveTable();
ArrayList<String> columnList = describeTable.describeTable(tableName, runFile.getParent());

采纳答案by Jeremy

The way to use Mockito is

使用 Mockito 的方法是

private DescribeHiveTable mockObj; // must be accessible to Test methods

@Before
public void initialize(){
    this.mockObj = Mockito.mock(DescribeHiveTable.class);
    <etc>
}

@Test
public void testComplexFeaturesExistingRun() {
    /* test the objects that are set up to use this.mockObj,
       and not the usual type of DescribeHiveTable */
}

Note that

注意

describeTable = new DescribeHiveTable();

means that you're using a new, unmocked, DescribeHiveTable, not the mocked mockObj.

意味着您使用的是新的、未模拟的DescribeHiveTable,而不是模拟的mockObj.

But it looks like you don't have control over the DescribeHiveTableinstance used by the DriverClass? If that's the case then either

但它看起来像你不必在控制DescribeHiveTable由所使用的实例DriverClass?如果是这样,那么要么

  • Mockito isn't going to help you -- or you at least have to mock the DriverClasstoo; or
  • you have to use reflection to replace the describeTablein DriverClasswith mockObj.
  • Mockito 不会帮助你——或者你至少也必须嘲笑它DriverClass;或者
  • 你必须使用反射来替换describeTableDriverClassmockObj

回答by Debojit Saikia

You can initialize the DriverClasswith a mock of DescribeHiveTable(provided DescribeHiveTableis an instance variable of DriverClass) as below:

您可以DriverClass使用模拟DescribeHiveTable(提供DescribeHiveTable的实例变量DriverClass)来初始化,如下所示:

public class TestClass{

@Mock
DescribeHiveTable mockObj;
// This will create a new instance of DriverClass with a mock of DescribeHiveTable
@InjectMocks
DriverClass driver;

@Before
    public void init() {

        MockitoAnnotations.initMocks(this);

        tableName = "clslog_assessments";
        parentDirectoryPath = "src/test/resources/TEST18/RunFiles";
        mockFeaturesArray1 = new String[] { "user_id", "event_id" };
        mockFeaturesList1 = new ArrayList<String>(
                Arrays.asList(mockFeaturesArray1));
        when(mockObj.describeTable(tableName, parentDirectoryPath)).thenReturn(
                mockFeaturesList1);
}

@Test
public void test() {
    // when(methodCall)
    assertEquals(mockFeaturesList1, driver.main());
}

}