使用MockContext时,在较新的Android版本中的ApplicationTestCase.createApplication()中的AssertionFailedError

时间:2013-01-06 13:57:23

标签: android android-4.0-ice-cream-sandwich android-testing

我正在编写一个Android ApplicationTestCase(第37页的Diego T. Milano的 Android应用程序测试指南中的TemperatureConverterApplicationTests示例)。这个例子是针对Android 2.3编写的,它似乎不适用于Android 4.你不必知道这本书来理解这个问题,因为我简化了它。

这适用于 Android 2.3.3 (API 10):

setContext(new MockContext());
createApplication();

[确切地说,抛出了UnsupportedOperationException,因为未实现getPackageName()。但这是正常的,可以通过使用实现getPackageName()和getSharedPreferences()的MockContext()子类来解决。这是不相关的,因为即使在执行此操作后问题仍然存在。]

问题在于,使用 Android 4.1.2 (API 16)它无效。我得到一个AssertionFailedError,通过一些调试我发现是由于在ApplicationTestCase的第100行抛出了ClassCastException。

mApplication = (T) Instrumentation.newApplication(mApplicationClass, getContext());

ClassCastException 消息为:

java.lang.ClassCastException: android.test.mock.MockContext cannot be cast to android.app.ContextImpl

为什么会发生这种情况以及如何避免这种情况的任何建议?

编辑:相关问题:Android ApplicationTestCase using a MockContext

2 个答案:

答案 0 :(得分:1)

我也有这种行为。我通过扩展ContextWrapper来解决这个问题:

public class RenamingMockContext extends RenamingDelegatingContext
{
    private static final String PREFIX = "test.";

    public RenamingMockContext(Context context)
    {
        super(new ContextWrapper(context), PREFIX);
    }

    @Override
    public String getPackageName()
    {
        return PREFIX + super.getPackageName();
    }
}

答案 1 :(得分:0)

Instrumentation.newApplication()方法将返回Application个对象。您正试图将其强制转换为T。如果T不是Application的超类或子类,您将获得ClassCastException。在Java中,您只能将对象强制转换为该对象的超类或子类。如果不是那么将抛出异常。

例如:

Object x = new Integer(0);
System.out.println((String)x);

这会在第二行引发ClassCastException,因为您尝试将xInteger个对象)投射到String。因为StringInteger不是彼此的子类或超类。