Androidunit testing需要上下文

我正在编写我的第一个Android数据库后端,我很努力地unit testing我的数据库的创build。

目前我遇到的问题是获取一个有效的上下文对象传递给我的SQLiteOpenHelper的实现。 有没有一种方法来获取扩展TestCase的类中的一个Context对象? 我想到的解决scheme是在我的TestCase的setup方法中实例化Activity,然后将该Activity的Context分配给我的testing方法可以访问的字段variables…但似乎应该有一个更简单的方法。

感谢您的input!

梅西

您可以尝试切换到AndroidTestCase 。 从看文档,它似乎应该能够为您提供一个有效的上下文传递给SQLiteOpenHelper。

编辑:请记住,您可能必须在Eclipse的“Androidtesting项目”中设置testing,因为testing将尝试在模拟器(或真实设备)上执行。

如果您正在使用AndroidJUnit4运行testing, AndroidJUnit4可以使用InstrumentationRegistry方法来获取上下文:

InstrumentationRegistry.getTargetContext() – 提供目标应用程序的应用程序Context ;

InstrumentationRegistry.getContext() – 提供了这个Instrumentation包的Context ;

根据我的经验,使用AndroidTestCase:getContext()方法仅提供了一个存根上下文。 对于我的testing,我在主应用程序中使用了一个空的活动,并通过它获取Context 。 我还用ActivityInstrumentationTestCase2类扩展了testing套件类。 似乎为我工作。

 public class DatabaseTest extends ActivityInstrumentationTestCase2<EmptyActivity> EmptyActivity activity; Context mContext = null; ... @Before public void setUp() { activity = getActivity(); mContext = activity; } ... //tests to follow } 

其他人做什么?

您应该使用ApplicationTestCase或ServiceTestCase。

扩展AndroidTestCase并调用AndroidTestCase:getContext()对我来说很好,可以获取Context并将其用于SQLiteDatabase。

唯一的问题是,它创build和/或使用的数据库将与生产应用程序使用的数据库相同,因此您可能需要使用不同的文件名

例如。

  public static final String NOTES_DB = "notestore.db"; public static final String DEBUG_NOTES_DB = "DEBUG_notestore.db"; 

你可以从MockContext派生出来,例如在getResources()返回一个MockResources ,在getContentResolver()等返回一个有效的ContentResolver 。这允许一些痛苦,一些unit testing

另一种方法是运行模拟整个Android操作系统的Robolectric 。 这些将是系统testing :运行速度慢很多。

首先在(androidTest)下创buildtesting类。

现在使用下面的代码:

 public class YourDBTest extends InstrumentationTestCase { private DBContracts.DatabaseHelper db; private RenamingDelegatingContext context; @Override public void setUp() throws Exception { super.setUp(); context = new RenamingDelegatingContext(getInstrumentation().getTargetContext(), "test_"); db = new DBContracts.DatabaseHelper(context); } @Override public void tearDown() throws Exception { db.close(); super.tearDown(); } @Test public void test1() throws Exception { // here is your context context = context; }} 

另一种解决scheme是避免使用ApplicationTestCaseAndroidTestCase或任何其他依赖于Context类。 重点在于不需要testingSQLiteORM框架,因此您可以使用基本的CRUD方法创build接口:

 public interface UsersManager{ User createUser(String userId); User getUser(String userId); boolean updateUser(User user); boolean deleteUser(User user); } 

并实现两个版本:一个用于testing,另一个用于生产运行时。 testing版本可以用HashMap轻松实现:

 public class TestUsersManager implements UsersManager{ private HashMap<String, User> users = new HashMap(); public User createUser(String userId){ User result = new User(userId); users.put(userId, user); return result; } //... other methods } 

它工作的很快( SQLite情况下没有磁盘IO ),并没有外部依赖。 顺便说一句,这也是额外的抽象层次:对于生产代码,您可以轻松地在ORM框架之间切换。