【问题标题】:How to get Locale from mock context如何从模拟上下文中获取语言环境
【发布时间】:2016-01-25 19:49:53
【问题描述】:

我正在尝试进行一些单元测试,但我还没有真正确定运行程序或测试类。

最后,这是我正在验证它是否有效的方法:

public static void getData(final Context context, final Callback<MyObject> callback) {

    Locale locale = context.getResources().getConfiguration().locale;
    MyObjectService myService = new MyObjectService(getRequestHeaders(context), locale);
}

所以我需要一个包含资源、配置、语言环境和 SharedPreferences 的模拟上下文。

我尝试过 PowerMockito、AndroidTestCase、AndroidTestRunner、ApplicationTestCase。我所能得到的只是一个没有任何内容的模拟上下文,或模拟资源,但我不知道如何将它们添加到模拟上下文(基本上是重新制作一个上下文)。

这是我目前的最后一次尝试(虽然我尝试过更复杂的,但没有任何成功):

导入 com.myApp.android.app.shop.util.ServiceUtils;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.modules.junit4.PowerMockRunner;

import android.content.Context;

@RunWith(PowerMockRunner.class)
public class TestLogin
{
    @Test
    public void test()
    {
        Context context = Mockito.mock(Context.class);
        ServiceUtils.getData(context, dataCallback);
    }
}

我得到的例外是来自 getData() 的 NPE,因为传递的上下文没有资源。

有什么建议吗?

【问题讨论】:

    标签: java android unit-testing junit mockito


    【解决方案1】:

    Android 不是一个容易模拟的系统。我也尝试过使用 Mockito 来模拟该框架,但它很快变得非常复杂。资源和 SharedPreferences 之类的东西不容易模拟。这些问题已在 Robolectric 等 3rd 方 API 中得到解决。

    我建议您使用 Robolectric 进行 Android 单元测试。 Robolectric 在标准 VM 中运行(即不需要模拟器)。 Robolectric 模拟了大多数 Android 系统,从而最大限度地减少(但不是消除)构建模拟的需要。我发现它对于 Android TDD 来说是一个非常有用的工具。

    【讨论】:

    • 感谢您的回答。到目前为止,我已经能够在基本测试中进行 robolectric 工作,但我无法验证回调返回的值。你知道怎么做吗?
    【解决方案2】:

    作为第二个答案(可能比第一个更有用),我建议您将逻辑从平台的依赖项中分离出来。

    这样你可以考虑以纯java的方式对逻辑进行单元测试。

    看看 MVP 模式。应该会有很大帮助!

    在这种情况下,例如,您将移动这条线...

    MyObjectService myService = new MyObjectService(getRequestHeaders(context), locale);
    

    ...在一个“服务”中,它完全是一个由构造函数分配的纯java类,需要(在这种情况下)一个名为“locale”的字符串值和一个名为“headers”的数据结构

    简单,不是吗? ;)

    我的 2 美分:每次您需要 Robolectric 来测试逻辑(而不是 UI)时,您可能会犯错误

    【讨论】:

    • 是的,这是一个选项,我们可以将这些方法分开。我一直在寻找针对现有方法和网络调用进行测试的选项。
    【解决方案3】:

    使用 Robolectric 的 RuntimeEnvironment

    Locale locale = RuntimeEnvironment.application.getResources().getConfiguration().locale;
    

    【讨论】:

    • 我刚刚做了,但我不知道如何验证改造 (1.9) 回调中的响应
    • 这是另一个问题:)
    • “验证响应”是什么意思?
    • 我现在正在使用 Robolectric,我得到这样的网络数据:“ServiceUtils.getData(context, dataCallback);”这是在 Before 方法或 Test 方法中。两者都有效。但是改造回调返回一个成功和失败的方法。在成功方法中,它返回一个对象。我需要用 Robolectric(或其他任何东西)验证这个对象,以验证数据是正确的对象类型并且其中包含正确的元素。
    猜你喜欢
    • 2021-11-20
    • 1970-01-01
    • 2022-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多