使用Robolectric的ShadowNfcAdapter对NFC辅助类进行单元测试

时间:2015-09-23 20:55:59

标签: android unit-testing nfc robolectric

我试图使用Robolectric来测试NFC助手类。简化,我做这样的事情:

Activity activity = Robolectric.buildActivity(Activity.class)
    .create()
    .start()
    .resume()
    .get();
NfcAdapter nfcAdapter = ShadowNfcAdapter.getNfcAdapter(activity);

然后运行我的NFC助手类,因为它做了类似的事情:

if (!nfcAdapter.isEnabled()){
  //more stuff
}

但是,调用nfcAdapter.isEnabled()会导致空指针异常。

java.lang.NullPointerException
at android.nfc.NfcAdapter.isEnabled(NfcAdapter.java:621)
at <package>.test_NfcIntent_shouldPostToBus(NfcHelperTest.java:49)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:251)
at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:188)
at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:54)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:152)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

该例外似乎来自Android NfcAdapter.java

public boolean isEnabled() {
    try {
        return sService.getState() == STATE_ON;
    } catch (RemoteException e) {
        attemptDeadServiceRecovery(e);
        return false;
    }
}

其中sService为空。实际上,当我使用调试器时,我可以看到nfcAdapter的字段都是null或者它们本身具有空字段的对象。

这是使用ShadowNfcAdapter的正确方法吗?或者,测试NFC助手类在触发时正确执行的正确方法是什么?

3 个答案:

答案 0 :(得分:2)

Coud你试试这样:

final Activity activty = Robolectric.setupActivity(Activity.class);
NfcAdapter adapter = NfcAdapter.getDefaultAdapter(activty);

final ShadowNfcAdapter shadowNfcAdapter = shadowOf(adapter);

shadowNfcAdapter.isEnabled()

答案 1 :(得分:1)

这是Robolectric的一个问题,我现在只有一种可能的解决方法就是编写自己的Shadow类。

我在Robolectric github https://github.com/robolectric/robolectric/issues/2059

上创建了问题

答案 2 :(得分:1)

使用robolectric 3.2.2

NfcManager manager = (NfcManager)  
context.getSystemService(Context.NFC_SERVICE);
NfcAdapter nfcAdapter = manager.getDefaultAdapter();
Shadows.shadowOf(nfcAdapter).setEnabled(true);