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.