gemfire cacheclosedexception 缓存尚未创建
gemfire cacheclosedexception the cache has not yet been created
我正在尝试为使用缓存实例的方法编写单元测试,如下所示
public void method(String abc) {
....
....
Cache cache = CacheFactory.getAnyInstance();
....
....
}
我知道模拟是解决缓存依赖的方法。我是模拟和使用 mockito 的新手,不确定如何将模拟缓存传递给方法。
@Mock
Cache cache;
@Test
public void testMethod(){
doReturn(cache).when(CacheFactory.getAnyInstance());
method("abc");
}
上面是我试过的,但是报错了。
如果您正在测试调用 CacheFactory.getAnyInstance()
(例如 method("abc")
?)的应用程序组件中的某些代码路径,那么您必须确保该方法以另一种方式获取对模拟缓存的引用因为你不能在 class 上模拟静态方法(即 getAnyInstance() on CacheFactory), at least not without some help from a framework like PowerMock。例如...
public class ExampleApplicationComponent {
public void methodUnderTest(String value) {
...
Cache hopefullyAMockCacheWhenTesting = CachFactory.getAnyInstance();
...
// do something with the Cache...
}
}
当然,这会失败。所以你需要稍微重构你的代码...
public class ExampleApplicationComponent {
public void methodUnderTest(String value) {
...
Cache cache = fetchCache();
...
// do something with the (mock) Cache...
}
Cache fetchCache() {
return CacheFactory.getAnyInstance();
}
}
然后在你的测试用例中 class...
public class ExampleApplicationComponentTest {
@Mock
private Cache mockCache;
@Test
public void methodUsesCacheProperly() {
ExampleApplicationComponent applicationComponent =
new ExampleApplicationComponent() {
Cache fetchCache() {
return mockCache;
}
};
applicationComponent.method("abc");
// assert appropriate interactions were performed on mockCache
}
}
因此,如您所见,您可以将测试用例中的匿名 ExampleApplicationComponent subclass 中的 fetchCache()
方法覆盖到 return 模拟缓存。另请注意,fetchCache()
方法是故意制作的 "package-private" 以限制它主要用于测试 class 的可访问性(因为测试 class 通常并且应该与class 测试中)。这可以防止 fetchCache
方法转义并成为您的 API 的一部分。虽然同一包中的其他 class 可以访问 ExampleApplicationComponent class 实例的方法,但您至少要重新训练对该用法的控制(当然,好的文档是不可替代的)。 =20=]
要在实践中查看其他示例,请查看 Spring Data GemFire 的 CacheFactoryBeanTest class (for instance, and specifically),它完全符合我上面描述的使用Mockito.
希望这对您有所帮助。
干杯!
-约翰
我能够在 PowerMockito 的帮助下做到这一点,下面是代码
mockStatic(CacheFactory.class);
when(CacheFactory.getAnyInstance()).thenReturn(cache);
method("abc");
verifyStatic();
CacheFactory.getAnyInstance();
我正在尝试为使用缓存实例的方法编写单元测试,如下所示
public void method(String abc) {
....
....
Cache cache = CacheFactory.getAnyInstance();
....
....
}
我知道模拟是解决缓存依赖的方法。我是模拟和使用 mockito 的新手,不确定如何将模拟缓存传递给方法。
@Mock
Cache cache;
@Test
public void testMethod(){
doReturn(cache).when(CacheFactory.getAnyInstance());
method("abc");
}
上面是我试过的,但是报错了。
如果您正在测试调用 CacheFactory.getAnyInstance()
(例如 method("abc")
?)的应用程序组件中的某些代码路径,那么您必须确保该方法以另一种方式获取对模拟缓存的引用因为你不能在 class 上模拟静态方法(即 getAnyInstance() on CacheFactory), at least not without some help from a framework like PowerMock。例如...
public class ExampleApplicationComponent {
public void methodUnderTest(String value) {
...
Cache hopefullyAMockCacheWhenTesting = CachFactory.getAnyInstance();
...
// do something with the Cache...
}
}
当然,这会失败。所以你需要稍微重构你的代码...
public class ExampleApplicationComponent {
public void methodUnderTest(String value) {
...
Cache cache = fetchCache();
...
// do something with the (mock) Cache...
}
Cache fetchCache() {
return CacheFactory.getAnyInstance();
}
}
然后在你的测试用例中 class...
public class ExampleApplicationComponentTest {
@Mock
private Cache mockCache;
@Test
public void methodUsesCacheProperly() {
ExampleApplicationComponent applicationComponent =
new ExampleApplicationComponent() {
Cache fetchCache() {
return mockCache;
}
};
applicationComponent.method("abc");
// assert appropriate interactions were performed on mockCache
}
}
因此,如您所见,您可以将测试用例中的匿名 ExampleApplicationComponent subclass 中的 fetchCache()
方法覆盖到 return 模拟缓存。另请注意,fetchCache()
方法是故意制作的 "package-private" 以限制它主要用于测试 class 的可访问性(因为测试 class 通常并且应该与class 测试中)。这可以防止 fetchCache
方法转义并成为您的 API 的一部分。虽然同一包中的其他 class 可以访问 ExampleApplicationComponent class 实例的方法,但您至少要重新训练对该用法的控制(当然,好的文档是不可替代的)。 =20=]
要在实践中查看其他示例,请查看 Spring Data GemFire 的 CacheFactoryBeanTest class (for instance, and specifically),它完全符合我上面描述的使用Mockito.
希望这对您有所帮助。
干杯! -约翰
我能够在 PowerMockito 的帮助下做到这一点,下面是代码
mockStatic(CacheFactory.class);
when(CacheFactory.getAnyInstance()).thenReturn(cache);
method("abc");
verifyStatic();
CacheFactory.getAnyInstance();