@ Mocked,@ Injectable和@Capturing有什么区别?

时间:2019-02-16 15:37:39

标签: java unit-testing jmockit

首先,我定义一个类,例如Robot

public class Robot {

    private Vision vision;

    public Object recognizeObject(List<List<Integer>> frames) {
        vision = new Vision();
        return vision.recognize(frames);
    }
}

Robot类具有多个依赖项,其中之一是Vision

public class Vision {

    public Object recognize(List<List<Integer>> frames) {
        // do magic stuff, but return dummy stuff
        return null;
    }

}

然后在测试类中,我只是测试recognize()的调用时间。

@RunWith(JMockit.class)
public class RobotTest {

    @Test
    public void recognizeObjectWithMocked(@Mocked final Vision vision) {
        List<List<Integer>> frames = new ArrayList<>();
        vision.recognize(frames);

        new Verifications() {{
            vision.recognize((List<List<Integer>>) any);
            times = 1;
        }};
    }

    @Test
    public void recognizeObjectWithInjectable(@Injectable final Vision vision) {
        List<List<Integer>> frames = new ArrayList<>();
        vision.recognize(frames);

        new Verifications() {{
            vision.recognize((List<List<Integer>>) any);
            times = 1;
        }};
    }

    @Test
    public void recognizeObjectWithCapturing(@Capturing final Vision vision) {
        List<List<Integer>> frames = new ArrayList<>();
        vision.recognize(frames);

        new Verifications() {{
            vision.recognize((List<List<Integer>>) any);
            times = 1;
        }};
    }
}

基于这些测试,我认为这3个注释可以互换使用。

  • 对吗?

  • 如果答案是否定的,那么在任何情况下,只有 @Mocked / @Injectable / @Capturing是可能的,不能替换为 另一个吗?

1 个答案:

答案 0 :(得分:2)

  • @Injectable模拟单个实例(例如,测试方法的参数)。并非每个实例都在测试上下文中使用。
  • @Mocked将在测试上下文中创建的每个实例上模拟所有类方法和构造函数。
  • @Capturing@Mocked基本相同,但是它将模拟扩展到带注释类型的每个子类型(方便!)。

@Injectable的另一个区别是,只有标记有此批注的字段才考虑在@Tested实例中注入。

现在区别应该很明显。