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是避免使用ApplicationTestCase
或AndroidTestCase
或任何其他依赖于Context
类。 重点在于不需要testingSQLite
或ORM
框架,因此您可以使用基本的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
框架之间切换。