需要上下文的 Android 单元测试

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2095695/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 04:31:25  来源:igfitidea点击:

Android Unit Tests Requiring Context

databaseandroidunit-testing

提问by Macy Abbey

I am writing my first Android database backend and I'm struggling to unit test the creation of my database.

我正在编写我的第一个 Android 数据库后端,并且正在努力对我的数据库的创建进行单元测试。

Currently the problem I am encountering is obtaining a valid Context object to pass to my implementation of SQLiteOpenHelper. Is there a way to get a Context object in a class extending TestCase? The solution I have thought of is to instantiate an Activity in the setup method of my TestCase and then assigning the Context of that Activity to a field variable which my test methods can access...but it seems like there should be an easier way.

目前我遇到的问题是获取一个有效的 Context 对象以传递给我的 SQLiteOpenHelper 实现。有没有办法在扩展 TestCase 的类中获取 Context 对象?我想到的解决方案是在我的 TestCase 的 setup 方法中实例化一个 Activity,然后将该 Activity 的 Context 分配给我的测试方法可以访问的字段变量......但似乎应该有更简单的方法。

Thanks for your input!

感谢您的输入!

Macy

梅西百货

采纳答案by Erich Douglass

You might try switching to AndroidTestCase. From looking at the docs, it seems like it should be able to provide you with a valid Context to pass to SQLiteOpenHelper.

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

Edit: Keep in mind that you probably have to have your tests setup in an "Android Test Project" in Eclipse, since the tests will try to execute on the emulator (or real device).

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

回答by birdy

You can use InstrumentationRegistrymethods to get a Context:

您可以使用InstrumentationRegistry方法来获取上下文:

InstrumentationRegistry.getTargetContext()- provides the application Contextof the target application.

InstrumentationRegistry.getTargetContext()- 提供Context目标应用程序的应用程序。

InstrumentationRegistry.getContext()- provides the Contextof this Instrumentation's package.

InstrumentationRegistry.getContext()- 提供了Context这个 Instrumentation 的包。



For AndroidX use InstrumentationRegistry.getInstrumentation().getTargetContext()or InstrumentationRegistry.getInstrumentation().getContext().

对于 AndroidX 使用InstrumentationRegistry.getInstrumentation().getTargetContext()InstrumentationRegistry.getInstrumentation().getContext().

回答by Tim Kist

Using the AndroidTestCase:getContext()method only gives a stub Context in my experience. For my tests, I'm using an empty activity in my main app and getting the Contextvia that. Am also extending the test suite class with the ActivityInstrumentationTestCase2class. Seems to work for me.

根据AndroidTestCase:getContext()我的经验,使用该方法只会提供一个存根上下文。对于我的测试,我在主应用程序中使用了一个空的 Activity 并Context通过它获取。我还使用ActivityInstrumentationTestCase2该类扩展了测试套件类。似乎对我有用。

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

What does everyone else do?

其他人都做什么?

回答by Ehsan

Your test is not a Unit test!!!

你的测试不是单元测试!!!

When you need

当你需要

  • Context
  • Read or Write on storage
  • Access Network
  • Or change any config to test your function
  • 语境
  • 读取或写入存储
  • 接入网
  • 或更改任何配置以测试您的功能

You are not writing a unit test.

您不是在编写单元测试。

You need to write your test in androidTestpackage

您需要在androidTest包中编写测试

回答by Wernight

You can derive from MockContextand return for example a MockResourceson getResources(), a valid ContentResolveron getContentResolver(), etc. That allows, with some pain, some unit tests.

您可以从MockContext派生并返回例如一个MockResourceson getResources(),一个有效的ContentResolverongetContentResolver()等。这允许一些单元测试,但有些痛苦。

The alternative is to run for example Robolectricwhich simulates a whole Android OS. Those would be for system tests: It's a lot slower to run.

替代方法是运行例如模拟整个 Android 操作系统的Robolectric。这些将用于系统测试:运行速度要慢得多。

回答by Neil

You should use ApplicationTestCase or ServiceTestCase.

您应该使用 ApplicationTestCase 或 ServiceTestCase。

回答by Ian

Extending AndroidTestCase and calling AndroidTestCase:getContext() has worked fine for me to get Context for and use it with an SQLiteDatabase.

扩展 AndroidTestCase 并调用 AndroidTestCase:getContext() 对我来说很好地获取上下文并将其与 SQLiteDatabase 一起使用。

The only niggle is that the database it creates and/or uses will be the same as the one used by the production application so you will probably want to use a different filename for both

唯一的小问题是它创建和/或使用的数据库将与生产应用程序使用的数据库相同,因此您可能希望为两者使用不同的文件名

eg.

例如。

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

回答by lidox

First Create Test Class under (androidTest).

首先在(androidTest)下创建测试类。

Now use following code:

现在使用以下代码:

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;
}}