How to mock a Android NFC Tag object for unit testing -


i'm working on android project needs nfc integration. want write (j)unit tests see if application can receive nfc intents (specifically action_tech_discovered) , put given tag (in nfcadapter.extra_tag) on bus system. surprise cannot create tag instance or mock one. can explain me how can (unit) test?

at point accept form of integration testing, process of:

  1. detect nfc intent
  2. get tag object
  3. put on bus wrapped in carddetectedevent.

i have phone nfc enabled , few cards testing.

android sdk version: 19
libraries used: robolectric, junit , mockito

it's possible create mock tag object instance using reflection (note not part of public android sdk, might fail future android versions).

  1. get createmocktag() method though reflection:

    class tagclass = tag.class; method createmocktagmethod = tagclass.getmethod("createmocktag", byte[].class, int[].class, bundle[].class); 
  2. define constants preparing mock tag instance:

    final int tech_nfc_a = 1; final string extra_nfc_a_sak = "sak";    // short (sak byte value) final string extra_nfc_a_atqa = "atqa";  // byte[2] (atqa value)  final int tech_nfc_b = 2; final string extra_nfc_b_appdata = "appdata";    // byte[] (application data bytes atqb/sensb_res) final string extra_nfc_b_protinfo = "protinfo";  // byte[] (protocol info bytes atqb/sensb_res)  final int tech_iso_dep = 3; final string extra_iso_dep_hi_layer_resp = "hiresp";  // byte[] (null nfca) final string extra_iso_dep_hist_bytes = "histbytes";  // byte[] (null nfcb)  final int tech_nfc_f = 4; final string extra_nfc_f_sc = "systemcode";  // byte[] (system code) final string extra_nfc_f_pmm = "pmm";        // byte[] (manufacturer bytes)  final int tech_nfc_v = 5; final string extra_nfc_v_resp_flags = "respflags";  // byte (response flag) final string extra_nfc_v_dsfid = "dsfid";           // byte (dsf id)  final int tech_ndef = 6; final string extra_ndef_msg = "ndefmsg";              // ndefmessage (parcelable) final string extra_ndef_maxlength = "ndefmaxlength";  // int (result getmaxsize()) final string extra_ndef_cardstate = "ndefcardstate";  // int (1: read-only, 2: read/write, 3: unknown) final string extra_ndef_type = "ndeftype";            // int (1: t1t, 2: t2t, 3: t3t, 4: t4t, 101: mf classic, 102: icode)  final int tech_ndef_formatable = 7;  final int tech_mifare_classic = 8;  final int tech_mifare_ultralight = 9; final string extra_mifare_ultralight_is_ul_c = "isulc";  // boolean (true: ultralight c)  final int tech_nfc_barcode = 10; final string extra_nfc_barcode_barcode_type = "barcodetype";  // int (1: kovio/thinfilm) 
  3. create tech-extras bundle tag type. instance, nfc-a tag ndef message:

    bundle nfcabundle = new bundle(); nfcabundle.putbytearray(extra_nfc_a_atqa, new byte[]{ (byte)0x44, (byte)0x00 }); //atqa type 2 tag nfcabundle.putshort(extra_nfc_a_sak , (short)0x00); //sak type 2 tag  bundle ndefbundle = new bundle(); ndefbundle.putint(extra_ndef_maxlength, 48); // maximum message length: 48 bytes ndefbundle.putint(extra_ndef_cardstate, 1); // read-only ndefbundle.putint(extra_ndef_type, 2); // type 2 tag ndefmessage myndefmessage = ...; // create ndef message ndefbundle.putparcelable(extra_ndef_msg, myndefmessage);  // add ndef message 
  4. prepare anti-collision identifier/uid tag (see tag.getid() method). e.g. 7-byte-uid type 2 tag:

    byte[] tagid = new byte[] { (byte)0x3f, (byte)0x12, (byte)0x34, (byte)0x56, (byte)0x78, (byte)0x90, (byte)0xab }; 
  5. then can create mock tag instance invoking createmocktag() method

    tag mocktag = (tag)createmocktagmethod.invoke(null,         tagid,                                     // tag uid/anti-collision identifier (see tag.getid() method)         new int[] { tech_nfc_a, tech_ndef },       // tech-list         new bundle[] { nfcabundle, ndefbundle });  // array of tech-extra bundles, each entry maps entry in tech-list 

once created mock tag object, can send part of nfc discovery intent. e.g. tech_discovered intent:

intent techintent = new intent(nfcadapter.action_tech_discovered); techintent.putextra(nfcadapter.extra_id, tagid); techintent.putextra(nfcadapter.extra_tag, mocktag); techintent.putextra(nfcadapter.extra_ndef_messages, new ndefmessage[]{ myndefmessage });  // optionally add ndef message 

you can send intent activity:

techintent.setcomponent(...); // or equivalent optionally set explicit receiver startactivity(techintent); 

the receiver can use mock tag object retrieve instances of technology classes. however, method requires io operations fail.


Comments

Popular posts from this blog

c# - Validate object ID from GET to POST -

node.js - Custom Model Validator SailsJS -

php - Find a regex to take part of Email -