简体   繁体   English

用 mockito 监视 lambda

[英]Spying a lambda with mockito

I have encountered an interesting issue while writing an unit test which involved mocking a lambda.在编写涉及模拟 lambda 的单元测试时,我遇到了一个有趣的问题。

@Test
public void spyingLambda() {
    final Supplier<String> spy = Mockito.spy((Supplier) () -> "1");
    spy.get();
}

Running this test fails with the following error:运行此测试失败并出现以下错误:

Mockito cannot mock/spy because : - final class Mockito 不能模拟/间谍,因为: - 最后一堂课

One workaround for the above issue is replacing the lambda with anonymous implementation:上述问题的一种解决方法是用匿名实现替换 lambda:

@Test
public void spyingAnonymousImplementation() {
    final Supplier<String> spy = Mockito.spy(new Supplier<String>() {
        @Override
        public String get() {
            return "1";
        }
    });
    spy.get();
}

Though both tests are exactly the same (the IDE suggest even replacing the anonymous implementation with lambda), the second test doesn't fail.尽管两个测试完全相同(IDE 建议甚至用 lambda 替换匿名实现),但第二个测试并没有失败。

I was wondering if this is a known issue which could be fixed in mockito or are there any other workarounds.我想知道这是否是可以在 mockito 中修复的已知问题,或者是否有任何其他解决方法。

Another way of dealing with this issue is the following:处理此问题的另一种方法如下:

/**
 * This method overcomes the issue with the original Mockito.spy when passing a lambda which fails with an error
 * saying that the passed class is final.
 */
public static <T> T spyLambda(final Class<T> lambdaType, final T lambda) {
    return mock(lambdaType, delegatesTo(lambda));
}

Which allows spying the lambda by changing the first method as following:它允许通过更改第一种方法来监视 lambda,如下所示:

@Test
public void spyingLambda() {
    final Supplier<String> spy = spyLambda(Supplier.class, () -> "1");
    spy.get();
}

Hopefully the above examples might help others who encounter the same issue.希望以上示例可以帮助遇到相同问题的其他人。

Just for the reference, to improve @alex's answer, you can also do仅供参考,为了改进@alex 的回答,您也可以这样做

public static <T> T spyLambda(final T lambda) {
    Class<?>[] interfaces = lambda.getClass().getInterfaces();
    MatcherAssert.assertThat(interfaces, IsArrayWithSize.arrayWithSize(1));
    return Mockito.mock((Class<T>) interfaces[0], delegatesTo(lambda));
}

and then simply spy it without specifying the type (eg, Supplier.class )然后简单地监视它而不指定类型(例如, Supplier.class

Callable<Integer> callable = spyLambda(() -> {
    return 42;
});
Supplier<Integer> supplier = spyLambda(() -> 42);
Runnable runnable = spyLambda(() -> System.out.println("42"));

You can allow final class mocking.您可以允许最终类模拟。 Create file src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker containing创建文件src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker包含

mock-maker-inline

https://www.baeldung.com/mockito-final#configure-mocktio https://www.baeldung.com/mockito-final#configure-mocktio

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM