I'm currently working on an Android project which needs NFC integration. Now I want to write some (j)unit tests to see if the application can receive NFC intents (specifically ACTION_TECH_DISCOVERED
) and put the given tag (in NfcAdapter.EXTRA_TAG
) on a bus system. However to my surprise I cannot create a Tag
instance or mock one. Can someone explain to me how I can (unit) test?
At this point I would even accept a form of integration testing, the process of:
- Detect the NFC Intent
- Get the
Tag
object - Put it on the bus wrapped in a
CardDetectedEvent
.
I have a phone with NFC enabled and a few cards for testing.
Android SDK version: 19
Libraries used: robolectric, junit and mockito
It's possible to create a mock tag object instance using reflection (note that this is not part of the public Android SDK, so it might fail for future Android versions).
Get the
createMockTag()
method though reflection:Define some constants for preparing the mock tag instance:
Create the tech-extras bundle for your tag type. For instance, for an NFC-A tag with an NDEF message:
Prepare an anti-collision identifier/UID for your tag (see
Tag.getId()
method). E.g. a 7-byte-UID for a Type 2 tag:Then you can create a mock tag instance by invoking the
createMockTag()
methodOnce you created that mock tag object, you can send it as part of an NFC discovery intent. E.g. for a
TECH_DISCOVERED
intent:You can then send this intent to your activity:
The receiver can even use the mock tag object to retrieve instances of the technology classes. However, any method that requires IO operations will fail.