【问题标题】:Object is not getting mocked. Throwing Null Pointer Exception对象没有被嘲笑。抛出空指针异常
【发布时间】:2014-12-17 16:11:52
【问题描述】:

我正在使用 mockito 框架运行我的代码。框架正在为一个实现创建模拟对象,而不是为其他对象创建任何模拟对象,因为它抛出了空指针异常。这是我的代码和输出:

package com.sohi;

import java.io.IOException;

import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.HTableInterface;
import org.apache.hadoop.hbase.client.HTablePool;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.util.Bytes;

public class HbaseExample {

    private HTablePool pool;

    private static final String HTABLE_NAME = "table1";

    public String getValue(String rowKey, String columnFamily, String columnName) throws IOException {

        HTableInterface table = pool.getTable(HTABLE_NAME);

        Get get = new Get(Bytes.toBytes(rowKey)).addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(columnName));

        System.out.println("Is table Null  ? " + (table == null));

        Result result = table.get(get);

        System.out.println("is result null ? " + (result == null));

        byte [] val = result.value();



        return Bytes.toString(val);
    }

}

我的 Mockito 测试课程是:


import static org.junit.Assert.*;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.HTablePool;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.util.Bytes;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;

import com.sohi.HbaseExample;


@RunWith(MockitoJUnitRunner.class)
public class HbaseExampleTest {

    @Mock
    HTablePool pool;

    @Mock
    HTable hTable;

    @Mock
    Result result;


    @InjectMocks
    HbaseExample hbase = new HbaseExample();

    private static final String HTABLE_NAME = "table1";

    private static final String ROW_KEY = "k1";
    private static final String COLUMN_FAMILY = "col1";
    private static final String COLUMN_NAME = "c1";

    private static final String CELL_VALUE = "v1";

    @Test
    public void test1() throws Exception {
        Get get1 = new Get(Bytes.toBytes(ROW_KEY)).addColumn(Bytes.toBytes(COLUMN_FAMILY), Bytes.toBytes(COLUMN_NAME));

        Mockito.when(pool.getTable(HTABLE_NAME)).thenReturn(hTable);
        Mockito.when(hTable.get(get1)).thenReturn(result);
        Mockito.when(result.value()).thenReturn(Bytes.toBytes(CELL_VALUE));

        String str = hbase.getValue(ROW_KEY, COLUMN_FAMILY, COLUMN_NAME);

        assertEquals(str, CELL_VALUE);

    }

}

输出是:

表是空的吗?错误的 结果是空的吗?真的

并且还在 result.value() 附近抛出空指针异常。

只有表对象被模拟了。

【问题讨论】:

    标签: java unit-testing junit hbase mockito


    【解决方案1】:

    问题出在这里:

     Mockito.when(hTable.get(get1)).thenReturn(result);
    

    这与您的实际调用不匹配,因为您的get1 不等于实际传递的Get 对象。 (看起来一样,但Get 不会覆盖equals(),因此使用将任意两个不同对象视为不相等的默认行为。)

    我建议您使用 Captor 来捕获 Get 对象并添加断言以验证是否存在正确的信息。 (无论如何,我认为这是编写此类测试的更好方法 - 它将所有断言放在一起,如果您传递了错误的内容,则会导致更好的错误消息。)

    【讨论】:

    • 我在其他工作空间中有相同的代码。但是在新的工作空间中,我遇到了这个问题。我不知道出了什么问题
    • 我敢打赌这不完全一样。您所拥有的将适用于许多覆盖equals() 的对象;但Get 不是其中之一。
    • 我知道了。我使用了两个版本的 Get。我在较旧的库中遇到了这个问题。当我在 Get 中包含 equals 时,它就起作用了。但我必须使用旧图书馆。如果是这样,那么我可以模拟该对象(因为它没有 equals 方法)。有什么建议吗?
    • 使用俘虏(见答案的最后一段和docs.mockito.googlecode.com/hg/1.9.5/org/mockito/Captor.html)。或者您可以编写自己的自定义参数匹配器 (docs.mockito.googlecode.com/hg/1.9.5/org/mockito/Matchers.html),但我认为这更麻烦。
    猜你喜欢
    • 1970-01-01
    • 2020-07-21
    • 2020-11-22
    • 2020-08-10
    • 2013-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多