简体   繁体   English

如何在Mockito的单元测试中模拟LocalCache

[英]How to mock LocalCache in unit testing with Mockito

My base class uses java library responsible for auditing. 我的基类使用负责审计的Java库。 This Library uses Builder pattern to retrieve objects from my Java Project for Auditing Operations ( Inserts into Multiple tables by creating keys on it's own. ) This Library uses com.google.common.cache to manage cache values. 该库使用Builder模式从Java项目中检索对象以进行审核操作( 通过自己创建键插入多个表中。 )该库使用com.google.common.cache来管理缓存值。 ie String and Value. 即字符串和值。 LoadingCache<String, Long>

sample Example of how my project uses library 我的项目如何使用库的示例

auditOperation = LibraryAuditBuilder.builder()
//some param
.build()
LibraryAuditingService.process(auditOperation);

My base application and Library runs on Oracle Database and my unit tests uses HSQL database. 我的基本应用程序和库在Oracle数据库上运行,而我的单元测试使用HSQL数据库。 Given all necessary scripts in @Before I would want to unit test execution of my code. 给定@Before所有必需的脚本,我想对代码的执行进行单元测试。

@Before method @Before方法

@Before
    public void setUp() throws Exception {
    MockitoAnnotations.initMocks(this);
//create db scrips and other declarations
}

I have tried 2 approach so far 到目前为止,我已经尝试了两种方法

1) Created LoadingCache and put sample values in it so that UnitTest can use it later in execution. 1)创建了LoadingCache并将示例值放入其中,以便UnitTest在以后的执行中可以使用它。

longLoadingCache.put("4028eeb0-1d2d-daba-011d-2e36e4b2110e",(long)203);
longLoadingCache.put("4028ee14-24b4-5221-0124-b47bbb1d1232",(long)102);

2) @Mock object of LoadingCache and values in it to be used later in Tests 2) LoadingCache @Mock对象及其中的值,稍后将在测试中使用

when(longLoadingCache.get("4028eeb0-1d2d-daba-011d-2e36e4b2110e")).thenReturn((long)203);     
when(longLoadingCache.get("4028ee14-24b4-5221-0124-b47bbb1d1232")).thenReturn((long)102);

Current output with both of above approach 以上两种方法的电流输出

- com.google.common.cache.CacheLoader$InvalidCacheLoadException: CacheLoader returned null for key 4028ee14-24b4-5221-0124-b47bbb1d1232.

So my question is, How Can I Pass/Mock values of Cache so that UnitTests don't have to look for values in Library class. 所以我的问题是, 如何传递/模拟Cache的值,以便UnitTest不必在Library类中查找值。

Consider creating your own facade bean wrapping the 3rd-party library (eg AuditProcessor). 考虑创建包装第3方库的自己的Facade bean(例如AuditProcessor)。 When the facade is injected using @Autowire or @Inject you can easily mock it in the test code and check if your wrapping facade (read: the library) has been properly used. 使用@Autowire或@Inject注入外观时,您可以轻松地在测试代码中对其进行模拟,并检查包装的外观(阅读:库)是否已正确使用。 If you don't trust the library you could unit test the wrapping facade and all corner cases in isolated environment without HSQL. 如果您不信任该库,则可以在没有HSQL的隔离环境中对包装外观和所有角落情况进行单元测试。 If you want even more control you could introduce an interface (eg IAuditProcessor) and create a dummy implementation which will be @Autowired in test using Spring profiles. 如果您想要更多的控制权,则可以引入一个接口(例如IAuditProcessor)并创建一个虚拟实现,该实现将在使用Spring配置文件的测试中通过@Autowired进行测试。

To summarize: 总结一下:

  • HSQL-based test should test if the facade is called when expected and with correct arguments 基于HSQL的测试应测试是否在预期时使用正确的参数调用了Facade
  • corner cases / caching should be tested separately in isolated test cases without HSQL / Spring context 极端情况/缓存应在没有HSQL / Spring上下文的隔离测试案例中分别进行测试

Although answer from @Lukasz was perfectly valid but required much more effort. 尽管@Lukasz的回答完全正确,但需要付出更多的努力。 After spending some hours I was able to create simpler solution for this problem. 花了几个小时后,我能够为这个问题创建更简单的解决方案。 Rather then @Mock ing LocalCache , I can just @Mock class(Library class) providing cache values, as they were static values we don't care how library itself retrieves it. 而不是@Mock ing LocalCache ,我只能提供缓存值的@Mock类(Library类),因为它们是静态值,我们不在乎库本身如何检索它。 something like following 像下面这样

 busAuditOperationDao = mock(BusAuditOperationDao.class);
 busAuditProcessDao = mock(BusAuditProcessDao.class);

in @Before method I can specify whatever values I want, which will be used in @test classes @Before方法中,我可以指定所需的任何值,这些值将在@test类中使用

when(busAuditOperationDao.getAuditOperationIdFromGuid("4028eeb0-1d2d-daba-011d-2e36e4b2110e")).thenReturn((long) 102);
when(busAuditProcessDao.getAuditProcessIdFromGuid("4028ee14-24b4-5221-0124-b47bbb1d1232")).thenReturn((long)203);

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

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