我在单元测试方面没有太多经验,尤其是Mockito,现在我遇到了以下情况。
class A {
void setField(String obj) {
}
Object execute() {
throw new RuntimeException("Meh!");
}
}
class B {
//function to be tested
static Object someMethod() {
A a = new A();
a.setField("test");
Object response = a.execute();
//logic here
return response;
}
}
class BTest() {
A aInstance = mock(A.class);
@Test
public void test_someMethod_when_exec_returns_X() {
when(aInstance.execute()).thenReturns("X");// doesn’t work
assertTrue("X", B.someMethod());
}
}
我想在a.execute()返回特定值时测试someMethod静态方法。 我知道,我可以创建A的模拟对象并将其传递给someMethod函数,这不是一个好的解决方案,因为我应该更改someMethod的签名。
在这种情况下,正确的解决方案是什么?
答案 0 :(得分:2)
如果您查看PowerMockito's documentation,您会发现以下内容符合您的要求:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.whenNew;
// execute the test with the appropriate runner
@RunWith(PowerMockRunner.class)
// prepare B for instrumentation so we can hack stuff inside
@PrepareForTest(B.class)
public class MyTest {
@Test
public void bShouldCallA() throws Exception {
// create a mock for A and configure its behaviour
A aMock = mock(A.class);
when(aMock.execute()).thenReturn("X");
// make sure that when A's constructor is called in the static method, the mock above is returned
whenNew(A.class).withNoArguments().thenReturn(aMock);
// do the actual invocation
Object actualResult = B.someMethod();
// check result and interactions
assertEquals("X", actualResult);
verify(aMock).setField("test");
}
}
答案 1 :(得分:1)
正如我所提到的,PowerMockito在android中不起作用,你可以用它来模拟android对象。这是工程解决方案:)
用于创建对象A的工厂类。
public class AFactory {
static private AFactory sInsntance = new AFactory();
public static AFactory createObject() {
return sInsntance.createInternally();
}
protected TMMethodBuilder createInternally() {
return new A();
}
//This function is only for testing, in order to inject factory
@Deprecated
public static void setFactory(AFactory mock) {
sInsntance = mock;
}
}
创建对象A:
A a = AFactory.createObject();
在Test项目中扩展AFactory并覆盖createInternally()方法以返回模拟对象。
public class AFactoryTest extends AFactory {
private static A a = mock(A.class);
@Override
protected TMMethodBuilder createInternally() {
return a;
}
}
因此,在测试类中,只需执行以下操作:
factory = new AFactoryTest();
a = factory.createInternally();
AFactory.setFactory(factory);
//
when(..).thenReturn();