I am using the Java HBase API to get a value from Hbase. This is my code.
public class GetViewFromHbaseBolt extends BaseBasicBolt {
private HTable table;
private String zkQuorum;
private String zkClientPort;
private String tableName;
public GetViewFromHbaseBolt(String table, String zkQuorum,
String zkClientPort) {
this.tableName = table;
this.zkQuorum = zkQuorum;
this.zkClientPort = zkClientPort;
}
@Override
public void prepare(Map config, TopologyContext context) {
try {
table = getHTable();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void execute(Tuple tuple, BasicOutputCollector collector) {
try {
if (tuple.size() > 0) {
Long dtmid = tuple.getLong(0);
byte[] rowKey = HBaseRowKeyDistributor.getDistributedKey(dtmid);
Get get = new Get(rowKey);
get.addFamily("a".getBytes());
Result result = table.get(get);
System.out.println(result);
byte[] bidUser = result.getValue("a".getBytes(),
"co_created_5076".getBytes());
collector.emit(new Values(dtmid, bidUser));
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("dtmi", "bidUser"));
}
// setting up the conections for Hbase
protected HTable getHTable() throws IOException {
HTable table = null;
Configuration conf;
conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.property.clientPort", zkClientPort);
conf.set("hbase.zookeeper.quorum", zkQuorum);
table = new HTable(conf, tableName);
return table;
}
This works fine. Now I am writing a Unit Test using the Mockito API. On my test class I am getting a java.langNullPointerException when this when(table.get(any(Get.class))).thenReturn(result); is called.
public class GetViewFromHbaseBoltTest {
@Mock
private TopologyContext topologyContext;
@Mock
private HTable table;
//HTable table = mock(HTable.class);
@Test
public void testExecute() throws IOException {
long dtmId = 350000000770902930L;
final byte[] COL_FAMILY = "a".getBytes();
final byte[] COL_QUALIFIER = "co_created_5076".getBytes();
// A mock tuple with a single dtmid
Tuple tuple = mock(Tuple.class);
when(tuple.size()).thenReturn(1);
when(tuple.getLong(0)).thenReturn(dtmId);
List<KeyValue> kvs = new ArrayList<KeyValue>();
kvs.add(new KeyValue(COL_FAMILY, COL_QUALIFIER, Bytes
.toBytes("ExpedtedBytes")));
Result result = new Result(kvs);
when(table.get(any(Get.class))).thenReturn(result);
BasicOutputCollector collector = mock(BasicOutputCollector.class);
GetViewFromHbaseBolt bolt = mock(GetViewFromHbaseBolt.class);
// Execute the bolt.
bolt.execute(tuple, collector);
ArgumentCaptor<Values> valuesArg = ArgumentCaptor
.forClass(Values.class);
verify(collector).emit(valuesArg.capture());
ArrayList<Object> d = valuesArg.getValue();
// verify
}
'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:
@Mock
private HBaseRowKeyDistributor hDist;
@Mock
private HTable table;
@Test
public 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
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With