Powermock 一直给我返回一个空对象而不是模拟对象
Powermock keeps returning me a null object not a mock
所以我正在查看测试中的模拟对象。
但是,当执行“Mockito.when(mock.getName()”部分代码时,以下测试将 return npe,这是因为模拟对象被 returned 为 null。
package com.example.activity;
import com.example.BuildConfig;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.rule.PowerMockRule;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricGradleTestRunner;
import org.robolectric.annotation.Config;
import static org.junit.Assert.assertTrue;
@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21)
@PowerMockIgnore({ "org.mockito.*", "org.robolectric.*", "android.*" })
@PrepareForTest(Static.class)
public class DeckardActivityTest {
@Rule
public PowerMockRule rule = new PowerMockRule();
@Mock
public ToBeMocked mock;
@Test
public void testSomething() throws Exception {
assertTrue(Robolectric.buildActivity(DeckardActivity.class).create().get() != null);
}
@Test
public void testStaticMocking() {
PowerMockito.mockStatic(Static.class);
Mockito.when(Static.staticMethod()).thenReturn(mock);
Mockito.when(mock.getName()).thenReturn("Mock");
assertTrue(Static.getResp().equals("Mock"));
}
}
和我们正在测试的简单 class
包 com.example.activity;
public class Static {
private static ToBeMocked toBeMocked;
public static ToBeMocked staticMethod() {
toBeMocked = new ToBeMocked();
return toBeMocked;
}
public static String getResp(){
return toBeMocked.getName();
}
}
所以我的理解一定是错误的。
我想做的是模拟 ToBeMocked class 依赖项,并告诉模拟对象在调用 getName 方法时如何响应。
谁能帮我看看为什么会出错,或者指出我一定误解了什么
是的,你理解错了。我的意思是你误解了模拟的工作原理。
您的方法 getResp
(在示例中)使用根本不会设置的内部状态,因为在您调用 PowerMockito.mockStatic(Static.class);
之后,所有对 Static.class
静态方法的调用都将是拦截。所以代码:
toBeMocked = new ToBeMocked();
return toBeMocked;
从不调用。
如果 getResp
使用 staticMethod()
那么您的代码将有效。
public static String getResp(){
return staticMethod().getName();
}
所以您有两种选择来解决您的问题:
- 按照我的指示重构你的代码
- 使用mock constructor模拟
toBeMocked = new ToBeMocked();
所以我正在查看测试中的模拟对象。 但是,当执行“Mockito.when(mock.getName()”部分代码时,以下测试将 return npe,这是因为模拟对象被 returned 为 null。
package com.example.activity;
import com.example.BuildConfig;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.rule.PowerMockRule;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricGradleTestRunner;
import org.robolectric.annotation.Config;
import static org.junit.Assert.assertTrue;
@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21)
@PowerMockIgnore({ "org.mockito.*", "org.robolectric.*", "android.*" })
@PrepareForTest(Static.class)
public class DeckardActivityTest {
@Rule
public PowerMockRule rule = new PowerMockRule();
@Mock
public ToBeMocked mock;
@Test
public void testSomething() throws Exception {
assertTrue(Robolectric.buildActivity(DeckardActivity.class).create().get() != null);
}
@Test
public void testStaticMocking() {
PowerMockito.mockStatic(Static.class);
Mockito.when(Static.staticMethod()).thenReturn(mock);
Mockito.when(mock.getName()).thenReturn("Mock");
assertTrue(Static.getResp().equals("Mock"));
}
}
和我们正在测试的简单 class
包 com.example.activity;
public class Static {
private static ToBeMocked toBeMocked;
public static ToBeMocked staticMethod() {
toBeMocked = new ToBeMocked();
return toBeMocked;
}
public static String getResp(){
return toBeMocked.getName();
}
}
所以我的理解一定是错误的。 我想做的是模拟 ToBeMocked class 依赖项,并告诉模拟对象在调用 getName 方法时如何响应。
谁能帮我看看为什么会出错,或者指出我一定误解了什么
是的,你理解错了。我的意思是你误解了模拟的工作原理。
您的方法 getResp
(在示例中)使用根本不会设置的内部状态,因为在您调用 PowerMockito.mockStatic(Static.class);
之后,所有对 Static.class
静态方法的调用都将是拦截。所以代码:
toBeMocked = new ToBeMocked();
return toBeMocked;
从不调用。
如果 getResp
使用 staticMethod()
那么您的代码将有效。
public static String getResp(){
return staticMethod().getName();
}
所以您有两种选择来解决您的问题:
- 按照我的指示重构你的代码
- 使用mock constructor模拟
toBeMocked = new ToBeMocked();