2

実際のデバイスで基本的なアクティビティを使用して、Spec オブジェクトを正常に生成できます。ただし、Robolectric を介して JVM で Android SDK を使用すると、Spec オブジェクトを再現できません。実際のデバイスと同じ動作を再現するには、Robolectric Unit Test で何を拡張する必要がありますか?

以下は、実際のデバイスで動作するコードです。

package net.lapasa.testkeypairgeneratorspec;

import android.os.Bundle;
import android.security.KeyPairGeneratorSpec;
import android.support.v7.app.AppCompatActivity;

import java.math.BigInteger;
import java.util.Calendar;

import javax.security.auth.x500.X500Principal;

public class MainActivity extends AppCompatActivity
{

    private static final String TEST_ALIAS = "TEST_ALIAS";
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        KeyPairGeneratorSpec.Builder builder = new KeyPairGeneratorSpec.Builder(this); //mock(KeyPairGeneratorSpec.Builder.class);
        KeyPairGeneratorSpec spec = getSpec(builder); // THIS WORK, NOT NULL

    }

    private KeyPairGeneratorSpec getSpec(KeyPairGeneratorSpec.Builder builder)
    {
        Calendar notBefore = Calendar.getInstance();
        Calendar notAfter = Calendar.getInstance();
        notAfter.add(Calendar.YEAR, 1);

        String alias = TEST_ALIAS;
        builder.setAlias(alias);
        builder.setSubject(new X500Principal(String.format("CN=%s, OU=%s", alias, getPackageName())));
        builder.setSerialNumber(BigInteger.ONE);
        builder.setStartDate(notBefore.getTime());
        builder.setEndDate(notAfter.getTime());
        KeyPairGeneratorSpec spec = builder.build();

        return spec;

    }


}

ただし、Robolectric Unit Test でこの動作を再現しようとすると、Spec オブジェクトが返されません。

package net.lapasa.testkeypairgeneratorspec;

import android.security.KeyPairGeneratorSpec;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;

import java.math.BigInteger;
import java.security.Security;
import java.util.Calendar;

import javax.security.auth.x500.X500Principal;

import static org.junit.Assert.assertNotNull;

@RunWith(RobolectricTestRunner.class)
public class SpecGenerationTest
{
    public SpecGenerationTest()
    {
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    }

    private KeyPairGeneratorSpec getSpec(KeyPairGeneratorSpec.Builder builder)
    {
        Calendar notBefore = Calendar.getInstance();
        Calendar notAfter = Calendar.getInstance();
        notAfter.add(Calendar.YEAR, 1);

        String alias = "Test Alias";
        builder.setAlias(alias);
        builder.setSubject(new X500Principal(String.format("CN=%s, OU=%s", alias, RuntimeEnvironment.application.getPackageName())));
        builder.setSerialNumber(BigInteger.ONE);
        builder.setStartDate(notBefore.getTime());
        builder.setEndDate(notAfter.getTime());
        KeyPairGeneratorSpec spec = builder.build();

        return spec;
    }

    @Test
    public void testGenerateSpec() throws Exception
    {
        KeyPairGeneratorSpec.Builder builder = new KeyPairGeneratorSpec.Builder(RuntimeEnvironment.application);
        KeyPairGeneratorSpec spec = getSpec(builder);

        assertNotNull(spec); // THIS DOESN'T WORK, WHY IS IT NULL?
    }
}

更新:ここでは、カスタム シャドウを作成しようとしていますが、それでも null を返します。パラメータが実際に -REAL OBJECT- に設定されているかどうかはわかりません

package shadow.net.lapasa.testkeypairgeneratorspec;

import android.content.Context;
import android.security.KeyPairGeneratorSpec;

import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.RealObject;
import org.robolectric.internal.Shadow;

import java.math.BigInteger;
import java.util.Date;

import javax.security.auth.x500.X500Principal;

@Implements(KeyPairGeneratorSpec.Builder.class)
public class ShadowKeyPairGeneratorSpecBuilder
{
    @RealObject
    private KeyPairGeneratorSpec.Builder builder;


    private Context context;
    private X500Principal subject;
    private BigInteger serialNumber;
    private Date startDate;
    private Date endDate;
    private String alias;

    public void __constructor__(Context context)
    {
        this.context = context;
    }


    /**
     * Sets the alias to be used to retrieve the key later from a KeyStore instance using the AndroidKeyStore provider.
     *
     * @param alias
     */
    @Implementation
    public void setAlias(String alias)
    {
        this.alias = alias;
        Shadow.directlyOn(builder, KeyPairGeneratorSpec.Builder.class).setAlias(alias);

    }

    /**
     * Sets the subject used for the self-signed certificate of the generated key pair.
     *
     * @param subject
     */
    @Implementation
    public void setSubject(X500Principal subject)
    {
        this.subject = subject;
        Shadow.directlyOn(builder, KeyPairGeneratorSpec.Builder.class).setSubject(subject);
    }


    /**
     * Sets the serial number used for the self-signed certificate of the generated key pair.
     *
     * @param serialNumber
     */
    @Implementation
    public void setSerialNumber(BigInteger serialNumber)
    {
        this.serialNumber = serialNumber;
        Shadow.directlyOn(builder, KeyPairGeneratorSpec.Builder.class).setSerialNumber(serialNumber);
    }


    /**
     * Sets the start of the validity period for the self-signed certificate of the generated key pair.
     *
     * @param startDate
     */
    @Implementation
    public void setStartDate(Date startDate)
    {
        this.startDate = startDate;
        Shadow.directlyOn(builder, KeyPairGeneratorSpec.Builder.class).setStartDate(startDate);
    }

    /**
     * Sets the subject used for the self-signed certificate of the generated key pair.
     *
     * @param endDate
     */
    @Implementation
    public void setEndDate(Date endDate)
    {
        this.endDate = endDate;
        Shadow.directlyOn(builder, KeyPairGeneratorSpec.Builder.class).setEndDate(endDate);
    }

    @Implementation
    public KeyPairGeneratorSpec build()
    {
//        KeyPairGeneratorSpec spec = Shadow.directlyOn(builder, KeyPairGeneratorSpec.Builder.class, "build", null);
        KeyPairGeneratorSpec spec = builder.setAlias(alias).setSubject(subject).setSerialNumber(serialNumber).setStartDate(startDate).setEndDate(endDate).build();
//        KeyPairGeneratorSpec spec = Shadow.directlyOn(builder, KeyPairGeneratorSpec.Builder.class).build();
        return spec; // Cannot instantiate KeyPairGeneratorSpec directly because it's not available publically. It can only be generated through KeyPairGeneratorSpec.Builder generator
    }
}
4

0 に答える 0