我正在嘗試測驗我創建的快取是否正常作業,并且對方法的重復呼叫實際上并未多次呼叫,而是從我的快取加載。
我正在使用 Google Guava 的 LoadingCache 來完成此操作。
所以我天真的方法是創建一個間諜,并驗證該方法是否被呼叫過一次。然后我發現因為 spy() 是一個裝飾器,所以我只能查看是否在該物件上呼叫了該方法。由于該方法正在被 LoadingCache 呼叫,我的間諜無法驗證它。
我如何最好地測驗我的快取是否被正確使用?
(注意:我可以創建一個 LoadingCache 依賴項,并檢查是否呼叫了正確的方法,但是我不知道我的快取是否在作業。也許哈希是以我沒有預料到的方式計算的,所以實際上每次都在呼叫該方法。我想實際看看效果)
private final LoadingCache<TaskDetails, byte[]> cache;
...
cache = CacheBuilder.newBuilder()
.maximumSize(cacheSize)
.expireAfterAccess(Duration.ofMinutes(cacheDurationInMinutes))
.build(CacheLoader.from(this::doTask));
public byte[] taskCaller(...) {
...
return cache.getUnchecked();
}
public byte[] doTask(...) {
if(something.doSomething() ... ) {
...
}
第一次測驗嘗試不起作用,Mockito 說:需要但沒有呼叫(該方法“從未呼叫”,因為間諜不知道快取呼叫它)
@Test
public void test() {
// given
TaskService spy = spy(
new TaskService(...)
);
// when
for (int i = 0; i < 3; i ) {
spy.taskCaller(...);
}
// then
//if caching is working, we should only do the real work once
verify(spy, times(1)).doTask(any(TaskDetails.class));
}
第二次嘗試:方法( something.doSomething() )中第一條陳述句出現 NullPointerException,我不完全確定原因,但我相信與以前相同的原因
@Test
public void test() {
// given
TaskService spy = spy(
new TaskService(...)
);
final int[] counter = {0};
when(spy.doTask(any())).thenAnswer(invocation -> {
counter[0] ;
return new byte[]{0,0,0,0};
});
// when
int run = 3;
for (int i = 0; i < run; i ) {
spy.taskCaller(...);
}
// then
//if caching is working, we should only do the real work once
assertThat(run).isEqualTo(counter[0]);
verify(spy, times(1)).doTask(any(TaskDetails.class));
}
uj5u.com熱心網友回復:
兩個想法:
- 啟用快取統計記錄,與快取互動,獲取快取統計資訊,然后驗證負載計數(可能還有其他統計資訊)是否符合您的預期。
- 為您創建
CacheLoader一個單獨的命名類而不是方法參考,將其實體傳遞給CacheBuilder.build(),并安排該實體作為測驗中的模擬。然后,您可以在模擬加載器上驗證方法呼叫計數和引數。
uj5u.com熱心網友回復:
我正在使用 Google Guava 的 LoadingCache 來完成此操作。
這才是重點。如果您足夠信任 Guava,為什么不相信它的測驗有效?
你寫快取了嗎?不,你沒有。然后不要將它作為單元測驗的一部分進行測驗:僅作為集成測驗的一部分,以及整個應用程式的其余部分。
只需測驗呼叫快取使用方法時是否呼叫了快取加載方法。
如果要測驗是否有快取,請對通用方法執行兩次呼叫,并驗證快取加載方法是否只呼叫了一次。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/324861.html
