使用Robolectric测试HostApduService

时间:2014-11-20 12:06:46

标签: android service robolectric apdu hce

我想用Robolectric测试来测试我的HostApduService,但我找不到测试我的服务的方法。测试服务的常规方法不适用于HostApduServices。有什么建议吗?

到目前为止我尝试过:

示例正常服务

public class MyNormalService extends Service {
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    public void doStuff(){
        // Logic
    }
}

示例HostApduservice

public class MyHostApduService extends HostApduService {

@Override
    public byte[] processCommandApdu(final byte[] commandApdu, Bundle extras) {
        // Do my stuff
    }
}

测试

@Config(emulateSdk = 18)
@RunWith(RobolectricTestRunner.class)
public class MyHostApduServiceTest {

    @Test
    public void testNormalService(){ // Succeeds
        MyNormalService service = new MyNormalService();
        assertNotNull(service); 
    }

    @Test
    public void testProcessCommandApdu1(){ // Fails
        MyHostApduService service = new MyHostApduService();
        assertNotNull(service);
    }
    @Test

    public void testProcessCommandApdu2(){ // Fails
        MyHostApduService service = Robolectric.buildService(MyHostApduService.class).create().get();
        assertNotNull(service);
    }
    @Test
    public void testProcessCommandApdu3(){ // Fails
        MyHostApduService service = Robolectric.setupService(MyHostApduService.class);
        assertNotNull(service);
    }
}

所有apdu测试都会导致同样的错误:

java.lang.RuntimeException: Stub!
    at android.nfc.cardemulation.HostApduService.__constructor__(HostApduService.java)
    at android.nfc.cardemulation.HostApduService.<init>(HostApduService.java:5)
    at com.abc.MyHostApduService.<init>(MyHostApduService.java:

testNormalService成功。

1 个答案:

答案 0 :(得分:0)

我使用了Android支持库中的Espresso Test Framework。 以下是我的基本测试如何提供成功的结果:

static void encrypt() throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
    // Here you read the cleartext.
    FileInputStream fis = new FileInputStream("data/cleartext");
    // This stream write the encrypted text. This stream will be wrapped by another stream.
    FileOutputStream fos = new FileOutputStream("data/encrypted");

    // Length is 16 byte
    // Careful when taking user input!!! http://stackoverflow.com/a/3452620/1188357
    SecretKeySpec sks = new SecretKeySpec("MyDifficultPassw".getBytes(), "AES");
    // Create cipher
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.ENCRYPT_MODE, sks);
    // Wrap the output stream
    CipherOutputStream cos = new CipherOutputStream(fos, cipher);
    // Write bytes
    int b;
    byte[] d = new byte[8];
    while((b = fis.read(d)) != -1) {
        cos.write(d, 0, b);
    }
    // Flush and close streams.
    cos.flush();
    cos.close();
    fis.close();
}



static void decrypt() throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
    FileInputStream fis = new FileInputStream("data/encrypted");

    FileOutputStream fos = new FileOutputStream("data/decrypted");
    SecretKeySpec sks = new SecretKeySpec("MyDifficultPassw".getBytes(), "AES");
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.DECRYPT_MODE, sks);
    CipherInputStream cis = new CipherInputStream(fis, cipher);
    int b;
    byte[] d = new byte[8];
    while((b = cis.read(d)) != -1) {
        fos.write(d, 0, b);
    }
    fos.flush();
    fos.close();
    cis.close();
}


//put the last part in the method
static void generate() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException{
    FileInputStream fis;
    FileOutputStream fos;
    CipherOutputStream cos;
    // File you are reading from
    fis = new FileInputStream("/tmp/a.txt");
    // File output
    fos = new FileOutputStream("/tmp/b.txt");

    // Here the file is encrypted. The cipher1 has to be created.
    // Key Length should be 128, 192 or 256 bit => i.e. 16 byte
    SecretKeySpec skeySpec = new SecretKeySpec("MyDifficultPassw".getBytes(), "AES"); 
    Cipher cipher1 = Cipher.getInstance("AES");  
    cipher1.init(Cipher.ENCRYPT_MODE, skeySpec);
    cos = new CipherOutputStream(fos, cipher1);
    // Here you read from the file in fis and write to cos.
    byte[] b = new byte[8];
    int i = fis.read(b);
    while (i != -1) {
        cos.write(b, 0, i);
        i = fis.read(b);
    }
    cos.flush();
}

这是对应的android依赖关系的样子:

@RunWith(AndroidJUnit4.class)
@LargeTest
public class HostApduServiceTest {

    @Rule
    public UiThreadTestRule uiThreadTestRule = new UiThreadTestRule();

    @Test
    public void testService() throws Throwable {
        uiThreadTestRule.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                MyHostApduService service = new MyHostApduService();
                Assert.assertNotNull(service);
            }
        });


    }
}