使用 EhCache3 进行 JUnit 测试
JUnit test with EhCache3
我创建了如下简单的缓存应用程序:
import org.ehcache.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.cache.CacheException;
import java.util.Map;
import java.util.concurrent.TimeUnit;
public class JsonObjectCacheManager {
private static final Logger logger = LoggerFactory.getLogger(JsonObjectCacheManager.class);
private final Cache<String, JsonObjectWrapper> objectCache;
//setting up cache
public JsonObjectCacheManager() {
CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
.withCache("jsonCache",
CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, JsonObjectWrapper.class,
ResourcePoolsBuilder.newResourcePoolsBuilder()
.heap(100, EntryUnit.ENTRIES)
.offheap(10, MemoryUnit.MB))
.withExpiry(Expirations.timeToLiveExpiration(Duration.of(5, TimeUnit.MINUTES)))
.withValueSerializingCopier()
.build())
.build(true);
objectCache = cacheManager.getCache("jsonCache", String.class, JsonObjectWrapper.class);
}
public void putInCache(String key, Object value) {
try {
JsonObjectWrapper objectWrapper = new JsonObjectWrapper(value);
objectCache.put(key, objectWrapper);
} catch (CacheException e) {
logger.error(String.format("Problem occurred while putting data into cache: %s", e.getMessage()));
}
}
public Object retrieveFromCache(String key) {
try {
JsonObjectWrapper objectWrapper = objectCache.get(key);
if (objectWrapper != null)
return objectWrapper.getJsonObject();
} catch (CacheException ce) {
logger.error(String.format("Problem occurred while trying to retrieveSpecific from cache: %s", ce.getMessage()));
}
logger.error(String.format("No data found in cache."));
return null;
}
public boolean isKeyPresent(String key){
return objectCache.containsKey(key);
}
}
JsonObjectWrapper 只是一个包装器 class 来包装对象,以便可以对其进行序列化。
@Getter
@Setter
@ToString
@AllArgsConstructor
public class JsonObjectWrapper implements Serializable {
private static final long serialVersionUID = 3588889322413409158L;
private Object jsonObject;
}
我编写的 JUnit 测试如下:
import org.junit.*;
import org.mockito.*;
import java.util.*;
import static org.junit.Assert.*;
@RunWith(MockitoJUnitRunner.class)
public class JsonObjectCacheManagerTest {
private JsonObjectCacheManager cacheManager;
private Map<String, Object> names;
@Before
public void setup(){
/*names = new HashMap(){
{
put("name1", "Spirit Air Lines");
put("name2", "American Airlines");
put("name3", "United Airlines");
}
};*/
//edited as per Henri's point and worked
names = new HashMap();
names.put("name1", "Spirit Air Lines");
names.put("name2", "American Airlines");
names.put("name3", "United Airlines");
cacheManager = new JsonObjectCacheManager();
}
@Test
public void isPresentReturnsTrueIfObjectsPutInCache() throws Exception {
//put in cache
cacheManager.putInCache("names",names);
assertTrue(cacheManager.isKeyPresent("names"));
}
@Test
public void cacheTest() throws Exception {
//put in cache
cacheManager.putInCache("names",names);
//retrieve from cache
Map<String, Object> namesFromCache = (Map<String, Object>) cacheManager.retrieveFromCache("names");
//validate against the cached object
// assertEquals(3, namesFromCache.size());
// assertEquals("American Airlines", namesFromCache.get("name2"));
}
}
我收到断言错误,指出缓存中不存在密钥。这意味着对象没有被添加到缓存中。
有什么办法可以做junit测试吗?感谢您的帮助。
编辑:
大家好,@Henri 指出了我的错误,它解决了我的问题。 :)
@Test
public void cacheTest() throws Exception {
cacheManager = Mockito.mock(JsonObjectCacheManager.class);
您必须不能模拟正在测试的class。
问题出在你的 HashMap 上。实例化它的方式创建了一个匿名内部 class。它保留对外部 class 实例的引用。这是测试class。并且测试 class 不可序列化。
如果您使用以下代码,所有测试都会顺利通过。
names = new HashMap();
names.put("name1", "Spirit Air Lines");
names.put("name2", "American Airlines");
names.put("name3", "United Airlines");
我创建了如下简单的缓存应用程序:
import org.ehcache.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.cache.CacheException;
import java.util.Map;
import java.util.concurrent.TimeUnit;
public class JsonObjectCacheManager {
private static final Logger logger = LoggerFactory.getLogger(JsonObjectCacheManager.class);
private final Cache<String, JsonObjectWrapper> objectCache;
//setting up cache
public JsonObjectCacheManager() {
CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
.withCache("jsonCache",
CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, JsonObjectWrapper.class,
ResourcePoolsBuilder.newResourcePoolsBuilder()
.heap(100, EntryUnit.ENTRIES)
.offheap(10, MemoryUnit.MB))
.withExpiry(Expirations.timeToLiveExpiration(Duration.of(5, TimeUnit.MINUTES)))
.withValueSerializingCopier()
.build())
.build(true);
objectCache = cacheManager.getCache("jsonCache", String.class, JsonObjectWrapper.class);
}
public void putInCache(String key, Object value) {
try {
JsonObjectWrapper objectWrapper = new JsonObjectWrapper(value);
objectCache.put(key, objectWrapper);
} catch (CacheException e) {
logger.error(String.format("Problem occurred while putting data into cache: %s", e.getMessage()));
}
}
public Object retrieveFromCache(String key) {
try {
JsonObjectWrapper objectWrapper = objectCache.get(key);
if (objectWrapper != null)
return objectWrapper.getJsonObject();
} catch (CacheException ce) {
logger.error(String.format("Problem occurred while trying to retrieveSpecific from cache: %s", ce.getMessage()));
}
logger.error(String.format("No data found in cache."));
return null;
}
public boolean isKeyPresent(String key){
return objectCache.containsKey(key);
}
}
JsonObjectWrapper 只是一个包装器 class 来包装对象,以便可以对其进行序列化。
@Getter
@Setter
@ToString
@AllArgsConstructor
public class JsonObjectWrapper implements Serializable {
private static final long serialVersionUID = 3588889322413409158L;
private Object jsonObject;
}
我编写的 JUnit 测试如下:
import org.junit.*;
import org.mockito.*;
import java.util.*;
import static org.junit.Assert.*;
@RunWith(MockitoJUnitRunner.class)
public class JsonObjectCacheManagerTest {
private JsonObjectCacheManager cacheManager;
private Map<String, Object> names;
@Before
public void setup(){
/*names = new HashMap(){
{
put("name1", "Spirit Air Lines");
put("name2", "American Airlines");
put("name3", "United Airlines");
}
};*/
//edited as per Henri's point and worked
names = new HashMap();
names.put("name1", "Spirit Air Lines");
names.put("name2", "American Airlines");
names.put("name3", "United Airlines");
cacheManager = new JsonObjectCacheManager();
}
@Test
public void isPresentReturnsTrueIfObjectsPutInCache() throws Exception {
//put in cache
cacheManager.putInCache("names",names);
assertTrue(cacheManager.isKeyPresent("names"));
}
@Test
public void cacheTest() throws Exception {
//put in cache
cacheManager.putInCache("names",names);
//retrieve from cache
Map<String, Object> namesFromCache = (Map<String, Object>) cacheManager.retrieveFromCache("names");
//validate against the cached object
// assertEquals(3, namesFromCache.size());
// assertEquals("American Airlines", namesFromCache.get("name2"));
}
}
我收到断言错误,指出缓存中不存在密钥。这意味着对象没有被添加到缓存中。
有什么办法可以做junit测试吗?感谢您的帮助。
编辑: 大家好,@Henri 指出了我的错误,它解决了我的问题。 :)
@Test public void cacheTest() throws Exception { cacheManager = Mockito.mock(JsonObjectCacheManager.class);
您必须不能模拟正在测试的class。
问题出在你的 HashMap 上。实例化它的方式创建了一个匿名内部 class。它保留对外部 class 实例的引用。这是测试class。并且测试 class 不可序列化。
如果您使用以下代码,所有测试都会顺利通过。
names = new HashMap();
names.put("name1", "Spirit Air Lines");
names.put("name2", "American Airlines");
names.put("name3", "United Airlines");