如何android单元测试和模拟静态方法 [英] How to android unit test and mock a static method
问题描述
我真的希望你可以帮助我,我觉得我已经把头发拉了好几天。
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 mockHelperUtils
with the usualMockito.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屋!