为什么动态部分模拟对 JMockit 的 @Injectable 不起作用?
Why doesn't dynamic partial mocking work for JMockit's @Injectable?
在以下未记录 Expectations
的测试用例中,我希望动态部分模拟功能将用于初始化的字段 A
和 B
在 UnitToTest
中使用 @Injectable
。但相反,方法调用总是被模拟。仅对静态部分模拟使用无效的过滤器值,可以调用真正的方法:
@Service
class A {
public String doSomething() { return "doSomething"; }
public String doSomethingElse() { return "doSomethingElse"; }
}
@Service
class B {
public String doSomething() { return "doSomething"; }
public String doSomethingElse() { return "doSomethingElse"; }
}
@Service
class UnitToTest {
@Autowired B b;
@Autowired A a;
public B getB() { return b; }
public A getA() { return a; }
}
public class TestClass {
@Tested UnitToTest unit;
// @Mocked({ "someInvalidFilter()" })
@Injectable A a;
// @Mocked({ "someInvalidFilter()" })
@Injectable B b;
@Test
public void test() {
// actual return value is always null if no invalid static partial
// mocking filters are specified above
assertEquals("doSomething", unit.getA().doSomething());
assertEquals("doSomethingElse", unit.getA().doSomethingElse());
assertEquals("doSomething", unit.getB().doSomething());
assertEquals("doSomethingElse", unit.getB().doSomethingElse());
}
}
对我来说,使用 JMockit 的动态部分模拟似乎不适用于 @Injectable
s。这是已知限制吗?
@Injectable
s 总是被注入到 @Tested
对象中,假设可以找到匹配的字段或构造函数参数;注入过程甚至考虑了 DI 注释,例如 @Inject
和 @Autowired
.
但是,@Injectable
实例总是创建为 未初始化(即没有状态)和完全模拟实例。另一方面,部分模拟适用于您在测试中实例化(和初始化)自己的 真实 个实例。
所以,您似乎要求的是可以将所述真实实例(部分模拟或不模拟)注入到 @Tested
对象中。实际上,这不受支持(调用 Deencapsulation.setField
除外),因为用户从未提出过激励用例。
也就是说,如果改成下面的样例测试就可以通过:
public class TestClass {
@Tested(fullyInitialized = true) UnitToTest unit;
@Test
public void test() {
assertEquals("doSomething", unit.getA().doSomething());
assertEquals("doSomethingElse", unit.getA().doSomethingElse());
assertEquals("doSomething", unit.getB().doSomething());
assertEquals("doSomethingElse", unit.getB().doSomethingElse());
}
}
以上是 集成 测试,但不是单元测试。
在以下未记录 Expectations
的测试用例中,我希望动态部分模拟功能将用于初始化的字段 A
和 B
在 UnitToTest
中使用 @Injectable
。但相反,方法调用总是被模拟。仅对静态部分模拟使用无效的过滤器值,可以调用真正的方法:
@Service
class A {
public String doSomething() { return "doSomething"; }
public String doSomethingElse() { return "doSomethingElse"; }
}
@Service
class B {
public String doSomething() { return "doSomething"; }
public String doSomethingElse() { return "doSomethingElse"; }
}
@Service
class UnitToTest {
@Autowired B b;
@Autowired A a;
public B getB() { return b; }
public A getA() { return a; }
}
public class TestClass {
@Tested UnitToTest unit;
// @Mocked({ "someInvalidFilter()" })
@Injectable A a;
// @Mocked({ "someInvalidFilter()" })
@Injectable B b;
@Test
public void test() {
// actual return value is always null if no invalid static partial
// mocking filters are specified above
assertEquals("doSomething", unit.getA().doSomething());
assertEquals("doSomethingElse", unit.getA().doSomethingElse());
assertEquals("doSomething", unit.getB().doSomething());
assertEquals("doSomethingElse", unit.getB().doSomethingElse());
}
}
对我来说,使用 JMockit 的动态部分模拟似乎不适用于 @Injectable
s。这是已知限制吗?
@Injectable
s 总是被注入到 @Tested
对象中,假设可以找到匹配的字段或构造函数参数;注入过程甚至考虑了 DI 注释,例如 @Inject
和 @Autowired
.
但是,@Injectable
实例总是创建为 未初始化(即没有状态)和完全模拟实例。另一方面,部分模拟适用于您在测试中实例化(和初始化)自己的 真实 个实例。
所以,您似乎要求的是可以将所述真实实例(部分模拟或不模拟)注入到 @Tested
对象中。实际上,这不受支持(调用 Deencapsulation.setField
除外),因为用户从未提出过激励用例。
也就是说,如果改成下面的样例测试就可以通过:
public class TestClass {
@Tested(fullyInitialized = true) UnitToTest unit;
@Test
public void test() {
assertEquals("doSomething", unit.getA().doSomething());
assertEquals("doSomethingElse", unit.getA().doSomethingElse());
assertEquals("doSomething", unit.getB().doSomething());
assertEquals("doSomethingElse", unit.getB().doSomethingElse());
}
}
以上是 集成 测试,但不是单元测试。