Jam*_*mes 13 java android unit-testing mockito powermock
嗨,我真的希望你能帮助我,我觉得我已经把头发拉了好几天了.
我正在尝试为方法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";
}
}
Run Code Online (Sandbox Code Playgroud)
接下来我要模拟的静态方法:
public class HelperUtils {
public static int fetchUsernameFromInternet(Context context) {
int userid = 0;
Log.i("HelperUtils ", "hello");
return userid;
}
}
Run Code Online (Sandbox Code Playgroud)
在其他语言中,这很容易,但我无法在Android中使用它.我尝试了Mockito,但似乎不支持静态方法
HelperUtils helper = Mockito.mock(HelperUtils.class);
Mockito.when(helper.fetchUsernameFromInternet(getContext())).thenReturn(1);
Run Code Online (Sandbox Code Playgroud)
这个错误
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(这个想法有时被称为"不要模拟你不拥有的类型")
我使用PowerMockito做到了这一点。
我正在使用AppUtils.class,它包含多个静态方法和功能。
静态功能:
public static boolean isValidEmail(CharSequence target) {
return target != null && EMAIL_PATTERN.matcher(target).matches();
}
Run Code Online (Sandbox Code Playgroud)
测试用例:
@RunWith(PowerMockRunner.class)
@PrepareForTest({AppUtils.class})
public class AppUtilsTest {
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
PowerMockito.mockStatic(AppUtils.class);
PowerMockito.when(AppUtils.isValidEmail(anyString())).thenCallRealMethod();
}
@Test
public void testValidEmail() {
assertTrue(AppUtils.isValidEmail("name@email.com"));
}
@Test
public void testInvalidEmail1() {
assertFalse(AppUtils.isValidEmail("name@email..com"));
}
@Test
public void testInvalidEmail2() {
assertFalse(AppUtils.isValidEmail("@email.com"));
}
}
Run Code Online (Sandbox Code Playgroud)
编辑1:
添加以下导入:
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
Run Code Online (Sandbox Code Playgroud)
希望这对您有帮助。
| 归档时间: |
|
| 查看次数: |
13940 次 |
| 最近记录: |