我嘲笑了HazelcastInstance及其IMap。我必须测试几个方法(添加,删除),这些方法被锁定,更新,按顺序解锁。但是当我尝试运行测试时,Mocked IMap对象显示零调用。 测试类如下:
@RunWith(PowerMockRunner.class)
public class Test {
@Mock
private HazelcastInstance hazelcastInstance;
@Mock
private IMap<Object, Object> imap; // but in actual class instead of Object (K, V) we are having Class Names. private IMap<ClassA,ClassB> imap;
private TestClass testClass;
@Mock
private ClassA a;
@Mock
private ClassB b;
@Test
public void testAdd() {
when(hazelcastInstance.getMap(anyString())).thenReturn(imap);
testClass.add(a, b);
verify(imap, times(1)).lock(any()); //supposed to be invoked (1 time). But it is showing as zero interaction
verify(imap, times(1)).unlock(any());
}
}
要测试的类如下。
public class TestClass {
private IMap<ClassA, ClassB> imap= Hazelcast.newHazelcastInstance().getMap("constant);
public void add(final ClassA key, final ClassB value) {
if (key == null) {
return;
}
try {
imap.lock(key);
imap.put(key, value, 3L, TimeUnit.SECONDS);
} finally {
imap.unlock(key);
}
}
}
答案 0 :(得分:1)
在您的情况下,有两个IMAP实例。第一个是模拟,第二个是由Hazelcast.newHazelcastInstance()
返回的真实imap。
问题在于TestClass.add()
方法使用了真实的imap,而验证则使用了模拟。因此互动次数为零。
您需要使用构造函数或setter将模拟注入到TestClass实例中。
测试的示例代码:
@RunWith(PowerMockRunner.class)
public class Test1 {
@InjectMocks
private TestClass testClass;
@Mock
private IMap<String, Long> imap;
@Test
public void testAdd() {
String key = "a key";
Long value = 123L;
testClass.add(key, value);
verify(imap, times(1)).lock(key);
verify(imap, times(1)).put(eq(key), eq(value), anyLong(), any(TimeUnit.class));
verify(imap, times(1)).unlock(key);
}
}
重构后的TestClass:
class TestClass {
private IMap<String, Long> imap;
public TestClass(IMap<String, Long> imap) {
this.imap = imap;
}
public void add(final String key, final Long value) {
if (key == null) {
return;
}
try {
imap.lock(key);
imap.put(key, value, 3L, TimeUnit.SECONDS);
} finally {
imap.unlock(key);
}
}
}
答案 1 :(得分:0)
问题是你嘲笑
@Mock
private HazelcastInstance hazelcastInstance;
当测试类调用时
Hazelcast.newHazelcastInstance()
在测试类中显示架构问题。将地图注入TestClass的最佳方法 - 传入构造函数参数。
public class TestClass {
private final IMap<ClassA, ClassB> imap;
public TestClass(IMap<ClassA, ClassB> imap) {
this.imap = imap;
}
现在您可以创建TestClass的实例
IMap imap = mock(IMap.class)
testClass = new TestClass(imap)
答案 2 :(得分:0)
创建自己的imap测试类并实现这样的方法
public class HazelcastMap implements IMap { private Map map = new HashMap(); @Override public void putAll(Map m) { } @Override public int size() { return 0; } @Override public boolean isEmpty() { return false; } @Override public boolean containsKey(Object key) { return map.containsKey(key); } @Override public boolean containsValue(Object value) { return false; } @Override public Object get(Object key) { return map.get(key); } @Override public Object put(Object key, Object value) { map.put(key, value); return value; } @Override public Object remove(Object key) { return null; } @Override public boolean remove(Object key, Object value) { return false; } @Override public void removeAll(Predicate predicate) { } @Override public void delete(Object key) { } @Override public void flush() { } @Override public Map getAll(Set keys) { return map; } @Override public void loadAll(boolean replaceExistingValues) { } @Override public void loadAll(Set keys, boolean replaceExistingValues) { } @Override public void clear() { } @Override public ICompletableFuture getAsync(Object key) { return null; } @Override public ICompletableFuture putAsync(Object key, Object value) { return null; } @Override public ICompletableFuture putAsync(Object key, Object value, long ttl, TimeUnit ttlUnit) { return null; } @Override public ICompletableFuture putAsync(Object key, Object value, long ttl, TimeUnit ttlUnit, long maxIdle, TimeUnit maxIdleUnit) { return null; } @Override public ICompletableFuture setAsync(Object key, Object value) { return null; } @Override public ICompletableFuture setAsync(Object key, Object value, long ttl, TimeUnit ttlUnit) { return null; } @Override public ICompletableFuture setAsync(Object key, Object value, long ttl, TimeUnit ttlUnit, long maxIdle, TimeUnit maxIdleUnit) { return null; } @Override public ICompletableFuture removeAsync(Object key) { return null; } @Override public boolean tryRemove(Object key, long timeout, TimeUnit timeunit) { return false; } @Override public boolean tryPut(Object key, Object value, long timeout, TimeUnit timeunit) { return false; } @Override public Object put(Object key, Object value, long ttl, TimeUnit ttlUnit) { return null; } @Override public Object put(Object key, Object value, long ttl, TimeUnit ttlUnit, long maxIdle, TimeUnit maxIdleUnit) { return null; } @Override public void putTransient(Object key, Object value, long ttl, TimeUnit ttlUnit) { } @Override public void putTransient(Object key, Object value, long ttl, TimeUnit ttlUnit, long maxIdle, TimeUnit maxIdleUnit) { } @Override public Object putIfAbsent(Object key, Object value) { return null; } @Override public Object putIfAbsent(Object key, Object value, long ttl, TimeUnit ttlUnit) { return null; } @Override public Object putIfAbsent(Object key, Object value, long ttl, TimeUnit ttlUnit, long maxIdle, TimeUnit maxIdleUnit) { return null; } @Override public boolean replace(Object key, Object oldValue, Object newValue) { return false; } @Override public Object replace(Object key, Object value) { return null; } @Override public void set(Object key, Object value) { } @Override public void set(Object key, Object value, long ttl, TimeUnit ttlUnit) { } @Override public void set(Object key, Object value, long ttl, TimeUnit ttlUnit, long maxIdle, TimeUnit maxIdleUnit) { } @Override public void lock(Object key) { } @Override public void lock(Object key, long leaseTime, TimeUnit timeUnit) { } @Override public boolean isLocked(Object key) { return false; } @Override public boolean tryLock(Object key) { return false; } @Override public boolean tryLock(Object key, long time, TimeUnit timeunit) throws InterruptedException { return false; } @Override public boolean tryLock(Object key, long time, TimeUnit timeunit, long leaseTime, TimeUnit leaseTimeunit) throws InterruptedException { return false; } @Override public void unlock(Object key) { } @Override public void forceUnlock(Object key) { } @Override public String addLocalEntryListener(MapListener listener) { return null; } @Override public String addLocalEntryListener(EntryListener listener) { return null; } @Override public String addLocalEntryListener(MapListener listener, Predicate predicate, boolean includeValue) { return null; } @Override public String addLocalEntryListener(EntryListener listener, Predicate predicate, boolean includeValue) { return null; } @Override public String addLocalEntryListener(MapListener listener, Predicate predicate, Object key, boolean includeValue) { return null; } @Override public String addLocalEntryListener(EntryListener listener, Predicate predicate, Object key, boolean includeValue) { return null; } @Override public String addInterceptor(MapInterceptor interceptor) { return null; } @Override public void removeInterceptor(String id) { } @Override public String addEntryListener(MapListener listener, boolean includeValue) { return null; } @Override public String addEntryListener(EntryListener listener, boolean includeValue) { return null; } @Override public boolean removeEntryListener(String id) { return false; } @Override public String addPartitionLostListener(MapPartitionLostListener listener) { return null; } @Override public boolean removePartitionLostListener(String id) { return false; } @Override public String addEntryListener(MapListener listener, Object key, boolean includeValue) { return null; } @Override public String addEntryListener(EntryListener listener, Object key, boolean includeValue) { return null; } @Override public String addEntryListener(MapListener listener, Predicate predicate, boolean includeValue) { return null; } @Override public String addEntryListener(EntryListener listener, Predicate predicate, boolean includeValue) { return null; } @Override public String addEntryListener(MapListener listener, Predicate predicate, Object key, boolean includeValue) { return null; } @Override public String addEntryListener(EntryListener listener, Predicate predicate, Object key, boolean includeValue) { return null; } @Override public EntryView getEntryView(Object key) { return null; } @Override public boolean evict(Object key) { return false; } @Override public void evictAll() { } @Override public Set keySet() { return null; } @Override public Collection values() { return null; } @Override public Set entrySet() { return null; } @Override public Set keySet(Predicate predicate) { return null; } @Override public Set entrySet(Predicate predicate) { return null; } @Override public Collection values(Predicate predicate) { return null; } @Override public Set localKeySet() { return null; } @Override public Set localKeySet(Predicate predicate) { return null; } @Override public void addIndex(String attribute, boolean ordered) { } @Override public LocalMapStats getLocalMapStats() { return null; } @Override public Object executeOnKey(Object key, EntryProcessor entryProcessor) { return null; } @Override public Map executeOnKeys(Set keys, EntryProcessor entryProcessor) { return null; } @Override public void submitToKey(Object key, EntryProcessor entryProcessor, ExecutionCallback callback) { } @Override public ICompletableFuture submitToKey(Object key, EntryProcessor entryProcessor) { return null; } @Override public Map executeOnEntries(EntryProcessor entryProcessor) { return null; } @Override public Map executeOnEntries(EntryProcessor entryProcessor, Predicate predicate) { return null; } @Override public QueryCache getQueryCache(String name) { return null; } @Override public QueryCache getQueryCache(String name, Predicate predicate, boolean includeValue) { return null; } @Override public QueryCache getQueryCache(String name, MapListener listener, Predicate predicate, boolean includeValue) { return null; } @Override public boolean setTtl(Object key, long ttl, TimeUnit timeunit) { return false; } @Override public Object aggregate(Supplier supplier, Aggregation aggregation, JobTracker jobTracker) { return null; } @Override public Object aggregate(Supplier supplier, Aggregation aggregation) { return null; } @Override public Collection project(Projection projection, Predicate predicate) { return null; } @Override public Collection project(Projection projection) { return null; } @Override public Object aggregate(Aggregator aggregator, Predicate predicate) { return null; } @Override public Object aggregate(Aggregator aggregator) { return null; } @Override public String getPartitionKey() { return null; } @Override public String getName() { return null; } @Override public String getServiceName() { return null; } @Override public void destroy() { } }