2017-01-10 19 views
2
@Component 
    public class LibraryService { 

     @Autowired 
     private BookService bookService; 

     private Cache<UUID, Book> bookCache = CacheBuilder.newBuilder().maximumSize(512).expireAfterWrite(15, TimeUnit.MINUTES).build(); 

     public void someMethod(UUID bookId) { 
      try { 
      Book book = bookCache.get(bookId,() -> bookService.findBookByUuid(bookId)); 
      //some operations 
      } catch (ExecutionException e) { 
      throw new ProcessingFailureException("Failed to load cache value", e); 
      } 

     } 

    } 

このクラスの単体テストを書く必要があり、次のようにGoogle Guavaキャッシュをモックしようとしました。Google Guavaキャッシュビルダーを模擬する方法は?

public class LibraryServiceTest { 

    @InjectMocks 
    private LibraryService service; 

    @Mock 
    private BookService bookService; 

    @Mock 
    private Cache<UUID, Book> bookCache; 

    @Before 
    public void initialize() { 
     MockitoAnnotations.initMocks(this); 
    } 

    @Test 
    public void testMethod() throws ExecutionException { 
     UUID bookId = UUID.randomUUID(); 
     Book book = new Book(); 

     when(bookCache.get(bookId,() -> bookService.findBookByUuid(bookId))).thenReturn(book); 

     service.someMethod(bookId); 
    } 
} 

いくつかのNullPointer例外があります。

com.google.common.util.concurrent.UncheckedExecutionException: java.lang.NullPointerException 
    at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2203) 
    at com.google.common.cache.LocalCache.get(LocalCache.java:3937) 
    at com.google.common.cache.LocalCache$LocalManualCache.get(LocalCache.java:4739) 
Caused by: java.lang.NullPointerException 

注:わかりました、私は方法をいくつかのテスト可能な方法を変更することができます。この場合、私はそれをすることができませんでした。

このブックキャッシュをモックする方法はありますか?

+0

'@ InjectMocks'は、既に割り当てられたランダムなプライベート変数を上書きしますか? 'CacheService'は' LibraryService'の**依存性**なのでもっとインタフェースに入れて考える必要があります - それで、それはインターフェイスされて注入されるべきです。実際、あなたがSpringを使っているとき、私は[Springキャッシュ](https://docs.spring.io/spring/docs/current/spring-framework-reference/html/cache.html) - バックエンドとしてGuavaの 'Cache'をサポートしているので、機能的にはあなたのコードは同じになります。 –

+0

ええ、私は理解していますが、現時点で実装を変更することはできませんでした。 –

+0

「BookService」が再びキャッシュされた本を読み込むためにもう一度呼び出されないことをテストできませんか?このクラスが書かれている方法では、 'Cache'は私的な実装の詳細なので、テストすべきではありません。期待される振る舞いが必要です。 ['Ticker'](https://github.com/google/guava/wiki/CachesExplained#testing-timed-eviction)も参照してください。しかし、コードを変更できない場合は、そのコードも変更できません。 –

答えて

2

getメソッド呼び出しを次のようにモックして、結果として期待されるブックインスタンスが得られるように引数が一致するようにしてください。

import static org.mockito.Matchers.any; 
import static org.mockito.Matchers.eq; 
import static org.mockito.Mockito.when; 
... 

public class LibraryServiceTest { 
    ... 

    @Test 
    public void testMethod() throws ExecutionException { 
     ... 
     when(bookCache.get(eq(bookId), any(Callable.class))).thenReturn(book); 
     ... 
    } 
} 
+0

ありがとう、これは動作しています –

関連する問題