jMockit - 如何使对 return 的构造函数调用成为模拟
jMockit - How make constructor invocation to return a mock
我们目前使用 Mockito + PowerMock 作为我们的主要模拟框架,并且在开始将我们的一些代码移至 java 8 后遇到了一些问题。
因此,我们决定评估 jMockit 作为替代方案。我对模拟概念有很好的理解,但我承认我对 jMockit 的经验非常有限。
然而,我在测试一些在我看来应该是非常基本的东西时遇到了问题:被测试的 class 在其构造函数中使用 new 创建了其他 class 的实例。那个新的调用是我想让 return 成为一个模拟实例的东西。
这是我正在使用的代码:
包裹 com.some.org.some.app;
import mockit.Expectations;
import mockit.Injectable;
import mockit.Mocked;
import org.testng.annotations.Test;
public class ClassUnderTestTest {
interface SomeService {
void doWork();
}
class ClassUnderTest {
private final SomeService service;
public ClassUnderTest() {
this.service = new SomeService() {
@Override
public void doWork() {
}
};
}
}
@Injectable
private SomeService mockService;
@Test
public void shouldBeAbleToMaskVariousNumbers() throws Exception {
new Expectations() {{
new ClassUnderTest();
result = mockService;
}};
}
}
当 运行 以上时,我得到以下异常:
java.lang.IllegalStateException: Missing invocation to mocked type at this point;
please make sure such invocations appear only after the declaration of a suitable
mock field or parameter
我使用 TestNG 作为测试框架,实际上我的测试方法有一堆参数,因为它期望数据提供者传递一些测试数据。
这是非常基本的,看起来我的方法不是 jMockit 方式。预先感谢您的支持。
使用 JMockit 很容易做到这一点:
public class ClassUnderTestTest {
interface SomeService { int doWork(); }
class ClassUnderTest {
private final SomeService service;
ClassUnderTest() {
service = new SomeService() {
@Override public int doWork() { return -1; }
};
}
int useTheService() { return service.doWork(); }
}
// This annotation is a variation on @Mocked, which extends
// mocking to any implementation classes or subclasses of
// the mocked base type.
@Capturing SomeService mockService;
@Test
public void shouldBeAbleToMaskVariousNumbers() {
new Expectations() {{ mockService.doWork(); result = 123; }};
int n = new ClassUnderTest().useTheService();
assertEquals(123, n);
}
}
我们目前使用 Mockito + PowerMock 作为我们的主要模拟框架,并且在开始将我们的一些代码移至 java 8 后遇到了一些问题。 因此,我们决定评估 jMockit 作为替代方案。我对模拟概念有很好的理解,但我承认我对 jMockit 的经验非常有限。
然而,我在测试一些在我看来应该是非常基本的东西时遇到了问题:被测试的 class 在其构造函数中使用 new 创建了其他 class 的实例。那个新的调用是我想让 return 成为一个模拟实例的东西。
这是我正在使用的代码: 包裹 com.some.org.some.app;
import mockit.Expectations;
import mockit.Injectable;
import mockit.Mocked;
import org.testng.annotations.Test;
public class ClassUnderTestTest {
interface SomeService {
void doWork();
}
class ClassUnderTest {
private final SomeService service;
public ClassUnderTest() {
this.service = new SomeService() {
@Override
public void doWork() {
}
};
}
}
@Injectable
private SomeService mockService;
@Test
public void shouldBeAbleToMaskVariousNumbers() throws Exception {
new Expectations() {{
new ClassUnderTest();
result = mockService;
}};
}
}
当 运行 以上时,我得到以下异常:
java.lang.IllegalStateException: Missing invocation to mocked type at this point;
please make sure such invocations appear only after the declaration of a suitable
mock field or parameter
我使用 TestNG 作为测试框架,实际上我的测试方法有一堆参数,因为它期望数据提供者传递一些测试数据。
这是非常基本的,看起来我的方法不是 jMockit 方式。预先感谢您的支持。
使用 JMockit 很容易做到这一点:
public class ClassUnderTestTest {
interface SomeService { int doWork(); }
class ClassUnderTest {
private final SomeService service;
ClassUnderTest() {
service = new SomeService() {
@Override public int doWork() { return -1; }
};
}
int useTheService() { return service.doWork(); }
}
// This annotation is a variation on @Mocked, which extends
// mocking to any implementation classes or subclasses of
// the mocked base type.
@Capturing SomeService mockService;
@Test
public void shouldBeAbleToMaskVariousNumbers() {
new Expectations() {{ mockService.doWork(); result = 123; }};
int n = new ClassUnderTest().useTheService();
assertEquals(123, n);
}
}