如何android单元测试和模拟静态方法 [英] How to android unit test and mock a static method

查看:121
本文介绍了如何android单元测试和模拟静态方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我真的希望你可以帮助我,我觉得我已经把头发拉了好几天。

Hi I really hope you can help me, I feel like I've been pulling my hair out for days.

我正在尝试编写单元测试方法A.方法A调用静态方法B.我想模拟静态方法B.

I'm trying to write unit tests for a method A. Method A calls a static method B. I want to mock static method B.

我知道之前已经问过,但我觉得Android已经成熟了然后,必须有一种方法可以完成这么简单的任务,而无需重新编写我想测试的方法。

I know this has been asked before, but I feel Android has matured since then, and there must be a way to do such a simple task without re-writing the methods I want to test.

这是一个例子,首先是我想要的方法测试:

Here is an example, first the method I want to test:

public String getUserName(Context context, HelperUtils helper) {
    if(helper == null){
        helper = new HelperUtils();
    }
    int currentUserId = helper.fetchUsernameFromInternet(context);

    if (currentUserId == 1) {
        return "Bob";
    } else {
        return "Unknown";
    }
}

接下来我要模拟的静态方法:

Next the static method I want to mock:

public class HelperUtils {
    public static int fetchUsernameFromInternet(Context context) {
        int userid = 0;

        Log.i("HelperUtils ", "hello");

        return userid;
    }
}

在其他语言中这很容易,但我可以不能让它在Android中运行。
我尝试了Mockito,但似乎不支持静态方法

In other languages this is so easy but I just can't make it work in Android. I've tried Mockito, but it appears static methods aren't supported

HelperUtils helper = Mockito.mock(HelperUtils.class);
Mockito.when(helper.fetchUsernameFromInternet(getContext())).thenReturn(1);

此错误


org.mockito.exceptions.misusing.MissingMethodInvocationException

org.mockito.exceptions.misusing.MissingMethodInvocationException

我已经尝试过Powermock但是我不完全确定这是支持的通过Android。我设法在我的gradle文件中使用androidCompile运行powermock但是我收到此错误:

I've tried Powermock but I'm not completely sure this is supported by Android. I managed to get powermock running using androidCompile in my gradle file but I get this error:


错误:任务执行失败':app: dexDebugAndroidTest。 com.android.ide.common.process.ProcessException:

Error:Execution failed for task ':app:dexDebugAndroidTest'. com.android.ide.common.process.ProcessException:

更不用说 PowerMockito.mockStatic(HelperUtils。 class); 不返回任何内容,所以我不知道将什么传递给我的getUsername方法!

Not to mention PowerMockito.mockStatic(HelperUtils.class); Doesn't return anything, so I don't know what to pass into my getUsername method!

任何帮助都会如此非常感谢。

Any help would be so very much appreciated.

推荐答案

静态方法与任何对象无关 - 您的 helper.fetchUsernameFromInternet( ...) HelperUtils.fetchUsernameFromInternet(...)相同(但有点令人困惑) - 你甚至应该得到编译器警告由于这个 helper.fetchUsernameFromInternet

Static methods aren't related to any object - your helper.fetchUsernameFromInternet(...) is the same (but a bit confusing) as HelperUtils.fetchUsernameFromInternet(...) - you should even get a compiler warning due to this helper.fetchUsernameFromInternet.

而且,而不是 Mockito.mock 模拟你必须使用的静态方法: @RunWith(...) @PrepareForTest(...)然后 PowerMockito.mockStatic(...) - 完整示例在这里: PowerMockito模拟单个静态方法和返回对象

What's more, instead of Mockito.mock to mock static methods you have to use: @RunWith(...), @PrepareForTest(...) and then PowerMockito.mockStatic(...) - complete example is here: PowerMockito mock single static method and return object

换句话说 - 模拟静态方法(以及构造函数)有点棘手。更好的解决方案是:

In other words - mocking static methods (and also constructors) is a bit tricky. Better solution is:


  • 如果你可以改变 HelperUtils ,那就做方法非静态,现在您可以使用通常的 Mockito.mock

  • if you can change HelperUtils, make that method non-static and now you can mock HelperUtils with the usual Mockito.mock

如果您无法更改 HelperUtils ,请创建一个包装类,该类委托给原始的 HelperUtils ,但没有静态方法,然后还使用通常的 Mockito.mock (这个想法)有时被称为不要模拟你不拥有的类型。)

if you can't change HelperUtils, create a wrapper class which delegates to the original HelperUtils, but doesn't have static methods, and then also use usual Mockito.mock (this idea is sometimes called "don't mock types you don't own")

这篇关于如何android单元测试和模拟静态方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆