簡體   English   中英

用 mockito 監視 lambda

[英]Spying a lambda with mockito

在編寫涉及模擬 lambda 的單元測試時,我遇到了一個有趣的問題。

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

運行此測試失敗並出現以下錯誤:

Mockito 不能模擬/間諜,因為: - 最后一堂課

上述問題的一種解決方法是用匿名實現替換 lambda:

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

盡管兩個測試完全相同(IDE 建議甚至用 lambda 替換匿名實現),但第二個測試並沒有失敗。

我想知道這是否是可以在 mockito 中修復的已知問題,或者是否有任何其他解決方法。

處理此問題的另一種方法如下:

/**
 * 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));
}

它允許通過更改第一種方法來監視 lambda,如下所示:

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

希望以上示例可以幫助遇到相同問題的其他人。

僅供參考,為了改進@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));
}

然后簡單地監視它而不指定類型(例如, Supplier.class

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

您可以允許最終類模擬。 創建文件src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker包含

mock-maker-inline

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM