我正在编写我的第一个Android数据库后端,我正在努力对我的数据库的创建进行单元测试。
目前我遇到的问题是获取一个有效的Context对象来传递给我的SQLiteOpenHelper实现。有没有办法在扩展TestCase的类中获取Context对象?我想到的解决方案是在我的TestCase的setup方法中实例化一个Activity,然后将该Activity的Context分配给我的测试方法可以访问的字段变量......但似乎应该有一个更简单的方法。
感谢您的投入!
梅西
答案 0 :(得分:40)
您可以尝试切换到AndroidTestCase。通过查看文档,它似乎应该能够为您提供有效的Context以传递给SQLiteOpenHelper。
编辑: 请记住,您可能必须在Eclipse中的“Android测试项目”中设置测试,因为测试将尝试在模拟器(或真实设备)上执行。
答案 1 :(得分:25)
如果您使用AndroidJUnit4
运行测试,则可以使用InstrumentationRegistry
方法获取上下文:
InstrumentationRegistry.getTargetContext()
- 提供目标应用程序的应用程序Context
。
InstrumentationRegistry.getContext()
- 提供此Instrumentation软件包的Context
。
对于AndroidX,请使用InstrumentationRegistry.getInstrumentation().getTargetContext()
或InstrumentationRegistry.getInstrumentation().getContext()
。
答案 2 :(得分:5)
根据我的经验,使用AndroidTestCase:getContext()
方法仅提供存根上下文。对于我的测试,我在我的主应用程序中使用了一个空活动并通过它获取Context
。我还使用ActivityInstrumentationTestCase2
类扩展了测试套件类。似乎对我有用。
public class DatabaseTest extends ActivityInstrumentationTestCase2<EmptyActivity>
EmptyActivity activity;
Context mContext = null;
...
@Before
public void setUp() {
activity = getActivity();
mContext = activity;
}
... //tests to follow
}
其他人都做了什么?
答案 3 :(得分:3)
您应该使用ApplicationTestCase或ServiceTestCase。
答案 4 :(得分:3)
您可以从MockContext派生,并在getResources()
上返回MockResources,在getContentResolver()
上返回有效ContentResolver,等等。痛苦,一些单元测试。
另一种方法是运行例如模拟整个Android操作系统的Robolectric。这些将用于系统测试:运行速度要慢得多。
答案 5 :(得分:2)
扩展AndroidTestCase并调用AndroidTestCase:getContext()对我来说很好,可以获取Context并将其与SQLiteDatabase一起使用。
唯一的问题是它创建和/或使用的数据库与生产应用程序使用的数据库相同,因此您可能希望为两者使用不同的文件名
例如。
public static final String NOTES_DB = "notestore.db";
public static final String DEBUG_NOTES_DB = "DEBUG_notestore.db";
答案 6 :(得分:0)
首先在(androidTest)下创建测试类。
现在使用以下代码:
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;
}}
答案 7 :(得分:0)
您的测试不是单元测试!
需要时
您不是在编写单元测试。
您需要使用androidTest
程序包编写测试
答案 8 :(得分:-1)
替代解决方案是避免使用ApplicationTestCase
或AndroidTestCase
或依赖Context
的任何其他类。关键是没有必要测试SQLite
或ORM
框架,因此您可以使用基本的CRUD
方法创建接口:
public interface UsersManager{
User createUser(String userId);
User getUser(String userId);
boolean updateUser(User user);
boolean deleteUser(User user);
}
实现两个版本:一个用于测试,另一个用于生产运行时。使用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
}
它运行速度很快(IO
)没有磁盘SQLite
并且没有外部依赖关系。顺便说一下,这也是额外的抽象级别:对于生产代码,您可以轻松地在ORM
框架之间切换。