当前位置: 首页 > 面试题库 >

如何进行Android单元测试和模拟静态方法

苗征
2023-03-14
问题内容

嗨,我真的希望您能为我提供帮助,我感觉我已经把头发拉了好几天了。

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

我知道以前已经有人问过这个问题,但是我觉得Android从那时起已经成熟,并且必须有一种方法可以执行如此简单的任务,而无需重写我要测试的方法。

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

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

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

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

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

        return userid;
    }
}

在其他语言中,这是如此简单,但我无法使其在Android中工作。我已经尝试过Mockito,但似乎不支持静态方法

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

这个错误

org.mockito.exceptions.misusing.MissingMethodInvocationException

我已经尝试过Powermock,但是我不能完全确定Android是否支持此功能。我设法在gradle文件中使用androidCompile使powermock运行,但是出现以下错误:

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

更不用说PowerMockito.mockStatic(HelperUtils.class);什么也不返回,所以我不知道该如何传递给我的getUsername方法!

任何帮助将非常感谢。


问题答案:

静态方法与任何对象都不相关-
您的对象与对象helper.fetchUsernameFromInternet(...)相同(但有点混乱)HelperUtils.fetchUsernameFromInternet(...)-因此,您甚至应该收到编译器警告helper.fetchUsernameFromInternet

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

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

  • 如果可以更改HelperUtils,请将该方法设置为非静态,然后可以HelperUtils使用通常的方法进行模拟Mockito.mock

  • 如果您不能更改HelperUtils,请创建一个包装类,该包装类委派给原始对象HelperUtils,但没有static方法,然后使用常规方法Mockito.mock(这种想法有时称为“不要嘲笑您不拥有的类型”)



 类似资料:
  • 嗨,我真的希望你能帮助我,我感觉我的头发已经拔了好几天了。 我正在尝试为一个方法a编写单元测试。方法a调用一个静态方法B。我想模拟静态方法B。 我知道以前有人问过这个问题,但我感觉Android从那以后已经成熟了,肯定有一种方法可以做到这么简单的任务,而不用重新编写我想测试的方法。 在其他语言中这是如此容易,但我就是无法使它在Android中工作。我试过Mockito,但似乎不支持静态方法 此错误

  • 我有一个这样的方法。 > 如果我模拟记录器,是否必须将方法更改为post(字符串json,记录器记录器)?否则,如何使此模拟与该方法交互?

  • 问题内容: 我正在尝试为一些依赖WifiManager和返回的ScanResults的类实现一些单元测试。我想做的是能够控制我收到的ScanResults,以测试各种不同的条件。 不幸的是,对我来说,成功模拟WifiManager非常困难(尽管我想我可以在MockWifiManager中传递其构造函数null引用)。这只是我的第一个问题,因为一旦我有一个MockWifiManager可以玩(如果它

  • 问题内容: 阅读并学习单元测试,尝试理解下面的文章,该文章解释了静态函数调用的困难。 我不清楚这个问题。我一直认为静态函数是在类中舍入实用函数的一种好方法。例如,我经常使用静态函数调用进行初始化,即: //阅读这篇文章后,我现在的目标是… 但是,我为此课程编写的几十个测试是相同的。我什么都没改变,他们仍然都过去了。难道我做错了什么? 该帖子的作者指出: 静态方法的基本问题是它们是过程代码。 我不知

  • 我有一个示例方法(我需要编写测试用例)如下所示, 我想模拟getConfig方法并返回一个特定的字符串值。getConfig是Kotlin对象中方法,如下所示, 下面是我尝试的测试 我没有得到任何错误,但是getConfig方法没有被嘲笑。执行实际的实现。我也试过使用Powermockito。请帮帮我

  • 我需要junit测试一段代码,但它从不同类调用的GsonConverter是静态方法,我无法更改。我不知道如何进行,因为我不能嘲笑它,因为它是静态的。 下面是带有静态方法的类