0

我正在尝试为使用缓存实例的方法编写单元测试,如下所示

public void method(String abc) {
....
....
Cache cache = CacheFactory.getAnyInstance();
....
....
}

我知道模拟是解决这种对缓存的依赖的方法。我是模拟和使用 mockito 的新手,不确定如何将模拟缓存传递给方法。

@Mock
Cache cache;

@Test
public void testMethod(){

   doReturn(cache).when(CacheFactory.getAnyInstance());
   method("abc");

}

以上是我尝试并得到错误的方法。

4

2 回答 2

0

如果您正在测试应用程序组件中调用的某些代码路径CacheFactory.getAnyInstance()(例如method("abc")?),那么您必须确保该方法以另一种方式获得对模拟缓存的引用,因为您无法模拟类上的静态方法(即getAnyInstance()在 CacheFactory 上),至少不是没有像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();
  }
}

然后在你的测试类中的测试用例中......

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
  }
}

如您所见,您可以fetchCache()在测试用例中覆盖匿名 ExampleApplicationComponent 子类中的方法以返回模拟缓存。另请注意,该fetchCache()方法被故意设为“包私有”以限制它对主要测试类的可访问性(因为测试类通常并且应该与被测类位于同一包中)。这可以防止fetchCache方法转义并成为 API 的一部分。虽然同一个包中的其他类可以访问 ExampleApplicationComponent 类的实例的方法,但您至少要重新训练对该用法的控制(当然,没有什么可以替代好的文档)。

要在实践中查看其他示例,请查看Spring Data GemFire 的 CacheFactoryBeanTest 类例如特别是),它完全按照我在上面使用 Mockito 描述的内容。

希望这可以帮助。

干杯! -约翰

于 2015-10-28T15:27:43.163 回答
0

我能够在 PowerMockito 的帮助下做到这一点,下面是代码

mockStatic(CacheFactory.class);
when(CacheFactory.getAnyInstance()).thenReturn(cache);

method("abc");

verifyStatic();
CacheFactory.getAnyInstance();
于 2015-11-03T22:56:40.717 回答