2015-11-05 20 views
1

我正在使用ApplicationTestCase测试一个Android应用程序。我想模仿我AsyncTasks(例如简化为说明问题)中的一个:为什么不使用AsyncTask进行模拟?

public class Foo extends AsyncTask<Void,Void,Void> { 
    @Override 
    protected Void doInBackground(Void... unused) { 
    return null; 
    } 
} 

因此,要建立我的测试,我做了以下内容:

private Foo mockFoo; 

@Override 
protected void setUp() throws Exception { 
    super.setUp() 

    mockFoo = mock(Foo.class); 

    createApplication(); 
} 

然后实际测试是以下:

public void testAsyncTaskMock() { 
    mockFoo.execute(); 
    verify(mockFoo).execute(); 
} 

,但我得到一个异常时,mockFoo.execute();运行:

java.lang.NullPointerException: Attempt to invoke virtual method 'int android.os.AsyncTask$Status.ordinal()' on a null object reference 

为什么嘲笑AsyncTask不起作用的技术?

请注意,删除createApplication();会导致此问题在此简单情况下消失,但对于我的实际测试,我确实需要创建应用程序。

回答

5

AsyncTask.execute是最后的,并且Mockito can't mock final classes or methods

  • 无法模拟最终方法 - 它们的实际行为没有任何例外地执行。 Mockito无法警告你嘲笑最后的方法,所以要提高警惕。

具体地说,这是因为Java可以解决在编译时链接的,这意味着可以的Mockito不能使用其产生的子类和方法重写来改变行为。

您可以选择使用Powermock,它使用一种特殊的类加载器重写旧的行为,或Robolectric,它不相同,但替换Android的特定测试友好的替代实现类(“影”)including one for AsyncTask

+0

Robolectric + 1!我喜欢它的理念 - 为什么要测试交互?改为测试效果。 – ZhongYu

相关问题