Unit testing JMockit:模拟接口的所有实现

Unit testing JMockit:模拟接口的所有实现,unit-testing,jmockit,Unit Testing,Jmockit,是否可以模拟接口的所有实现 我想模拟WatchService接口,如下所示 公共类服务测试{ @Test public void callTest( @Capturing @Injectable final WatchService ws ) throws Exception { final CountDownLatch latch = new CountDownLatch(1); new MockUp<ServiceTest

是否可以模拟接口的所有实现

我想模拟WatchService接口,如下所示

公共类服务测试{

@Test
public void callTest(
        @Capturing
        @Injectable
        final WatchService ws
) throws Exception {
    final CountDownLatch latch = new CountDownLatch(1);
    new MockUp<ServiceTest>() {
        @Mock(invocations = 1)
        public void onChange() {
            latch.countDown();
        }
    };

    new NonStrictExpectations() {
        {
            ws.take();
            result = new Delegate() {
                WatchKey take(Invocation inv) {
                    System.out.println("> " + inv.getInvokedInstance());

                    try {
                        new File("target/newFile").createNewFile();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    return inv.proceed();
                }
            };
        }
    };

    final Thread thread = new Thread() {
        @Override
        public void run() {

            final Path target = Paths.get("target");
            final FileSystem fs = target.getFileSystem();

            try {
                try (WatchService watcher = fs.newWatchService()) {
                    target.register(watcher, ENTRY_CREATE);

                    while (!Thread.currentThread().isInterrupted()) {
                        WatchKey take = watcher.take();
                        onChange();
                        System.out.println("take " + take);
                    }

                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };

    thread.start();


    assertTrue("", latch.await(5, TimeUnit.SECONDS));
    thread.interrupt();

}

private void onChange() {
    System.out.println("CHANGE");
}
@测试
公开无效调用测试(
@捕获
@注射的
最终监视服务
)抛出异常{
最终倒计时闩锁=新倒计时闩锁(1);
新模型(){
@模拟(调用=1)
更改后的公共无效(){
倒计时();
}
};
新的非严格测量(){
{
ws.take();
结果=新委托(){
监视键获取(调用inv){
System.out.println(“>”+inv.getInvokedInstance());
试一试{
新文件(“目标/newFile”).createNewFile();
}捕获(IOE异常){
e、 printStackTrace();
}
返回库存继续();
}
};
}
};
最终螺纹=新螺纹(){
@凌驾
公开募捐{
最终路径目标=Path.get(“目标”);
final FileSystem fs=target.getFileSystem();
试一试{
try(WatchService watcher=fs.newWatchService()){
目标.寄存器(观察者,条目\创建);
而(!Thread.currentThread().isInterrupted()){
WatchKey-take=watcher.take();
onChange();
System.out.println(“take”+take);
}
}
}捕获(例外e){
e、 printStackTrace();
}
}
};
thread.start();
assertTrue(“,lack.await(5,TimeUnit.SECONDS));
thread.interrupt();
}
私有void onChange(){
系统输出打印项次(“更改”);
}

如何实现这一点?

您可以在接口类型的模拟字段或模拟参数上使用
@Capturing
注释。下面是一个完整的示例测试(减去导入)

公共类CapturingAndProceedingTest{
静态类WatchKey{String key;WatchKey(String k){key=k;}
公共接口WatchService{public abstract WatchKey take();}
静态类WatchServiceImpl1实现WatchService{
@重写公共WatchKey take(){返回新的WatchKey(“Abc”);}
}
静态类WatchServiceImpl2实现WatchService{
@重写公共WatchKey take(){返回新的WatchKey(“123”);}
}
@试验
公共虚拟接口的实施(
@捕获//以便模拟所有实现类
@可注入//以便支持调用#继续()
最终值班服务值班服务
) {
最终列表服务=新的ArrayList();
//记录一个期望值,该期望值将匹配到的所有调用
//WatchService#take(),在实现接口的任何类上。
新的非严格测量(){{
watchService.take();
结果=新委托(){
WatchKey take(调用inv)引发IOException{
//在这里做点什么。。。
WatchService=inv.getInvokedInstance();
服务。添加(服务);
//…然后进行真正的实施。
返回库存继续();
}
};
}};
//实例化并使用接口的不同实现。
WatchServiceImpl1 impl1=新的WatchServiceImpl1();
assertEquals(“Abc”,impl1.take().key);
WatchServiceImpl2 impl2=新的WatchServiceImpl2();
assertEquals(“123”,impl2.take().key);
assertEquals(Arrays.asList(impl1、impl2)、services);
系统输出打印LN(服务);
}
}

有关更多示例,请参阅。

捕获只会让我得到由JMockit创建的模拟,而不是被模拟的类的真实实现。我需要能够“拦截”调用,执行一些东西并继续原始实现。如果我看不清楚,请提供一个示例。答案中链接的示例演示了您想要的内容,减去“继续原始实现”部分,该部分可以通过
调用#继续()完成
来自委托方法。您可以使用
@Capturing
编辑问题以包含您的示例测试吗?这不符合预期?您好!感谢您的帮助。我丢失了@Injectable。很抱歉,这让您失望,但它不起作用,因为事实上它被拦截了,我们收到了正确的实例,但是然后代码就不会恢复到原来的状态。因此,我的代码中在ws.take()之后的指令(在实际实现中)没有运行。我将把代码放在第一篇文章中。您能展示一个失败的完整示例测试吗?因为我无法从该片段中看出问题所在。
public class CapturingAndProceedingTest {
    static class WatchKey { String key; WatchKey(String k) {key = k;} }
    public interface WatchService { public abstract WatchKey take(); }
    static class WatchServiceImpl1 implements WatchService {
        @Override public WatchKey take() { return new WatchKey("Abc"); }
    }
    static class WatchServiceImpl2 implements WatchService {
        @Override public WatchKey take() { return new WatchKey("123"); }
    }

    @Test
    public void mockAllImplementationsOfAnInterface(
        @Capturing  // so that all implementing classes are mocked
        @Injectable // so that Invocation#proceed() is supported
        final WatchService watchService
    ) {
        final List<WatchService> services = new ArrayList<>();

        // Record an expectation that will match all calls to 
        // WatchService#take(), on any class implementing the interface.
        new NonStrictExpectations() {{
            watchService.take();
            result = new Delegate() {
                WatchKey take(Invocation inv) throws IOException {
                    // Do something here...
                    WatchService service = inv.getInvokedInstance();
                    services.add(service);

                    // ...then proceed to the real implementation.
                    return inv.proceed();
                }
            };
        }};

        // Instantiate and use different implementations of the interface.
        WatchServiceImpl1 impl1 = new WatchServiceImpl1();
        assertEquals("Abc", impl1.take().key);
        WatchServiceImpl2 impl2 = new WatchServiceImpl2();
        assertEquals("123", impl2.take().key);

        assertEquals(Arrays.asList(impl1, impl2), services);
        System.out.println(services);
    }
}