How to unit test Java Hbase API How to unit test Java Hbase API hadoop hadoop

How to unit test Java Hbase API


Edit

'Unit Test' is to verify, and validate a particular 'unit of code'. If that 'unit of code' depends on external calls, then we mock those calls to return certain values.

If you don't invoke the 'actual unit of code' from your test case, then what is the point in unit testing the code. got it?

You should mock only external calls from actual method, not the actual method itself.

So I would mock like:

@Mockprivate HBaseRowKeyDistributor hDist;@Mockprivate HTable table;@Testpublic void sampleTest(){    //Mock data and external calls    final byte [] COL_FAMILY = "a".getBytes();    final byte [] COL_QUALIFIER = "co_created_5076".getBytes();    List<KeyValue> kvs =new ArrayList<KeyValue>();    kvs.add(new KeyValue(COL_FAMILY, COL_QUALIFIER,                           Bytes.toBytes("ExpedtedBytes")));     Result result = new Result(kvs);     byte[] rowKey = "Hello".getBytes();     when(hdist.getDistributedKey(anyString()).thenReturn(rowKey);     when(table.get(any(Get.class))).thenReturn(result);     //Call the actual method     calloriginalUnitTestingMethod();     //Now Verify the result using Mockito verify like     verify(...)     //You could also intercept the attributes}


Maybe you noticed that your code is bad testable. The reason for the bad testability is that your class do two things (create a table and execute a tuple). I would recommand you to split your class into two classes and inject the class which create the table into the class which execute a tuple.

This class create a Table:

public class HTableFactory {    private String tablename;        public HTableFactory(String tablename) {        this.tablename = tablename;    }    public HTable getTable() {}}

Then your GetViewFromHbaseBolt class look something like the following:

public class GetViewFromHbaseBolt extends BaseBasicBolt {    private HTableFactory factory;    private HTable table;    public GetViewFromHbaseBolt(HTableFactory factory) {}    @Override    public void prepare(Map config, TopologyContext context) {        table = factory.getTable();    }    @Override    public void execute(Tuple tuple, BasicOutputCollector collector) {}    @Override    public void declareOutputFields(OutputFieldsDeclarer declarer) {}}

Now your GetViewFromHbaseBolt has the following dependencies:

  • HTableFactory
  • Tuple
  • BasicOutputCollector
  • OutputFieldsDeclarer

In your testclass you can mock out this dependencies and inject them into GetViewFromHbaseBold.


Have you checked that you initialize your mocks right? I am not an expert on Mockito but it seems to me you need to either set the test runner to Mockito runner or explicitly initialize the annotated mocks (@Mock). For example, see Using @Mock and @InjectMocks

My guess is your "table" variable is null when you run the line that produces the NullPointer.