繁体   English   中英

使用 JUnit 和 Mockito 测试内部类的重写方法

[英]Test an overridden method of an inner class with JUnit and Mockito

我在需要测试的类中有一个方法。 该方法使用我需要模拟的外部类,因此不会对外部类进行测试或执行其依赖项。 特殊的挑战是:外部类的一种方法被覆盖。 方法如下所示:

public void fetchLocalData(final String source, final ObservableEmitter<String> destination) {
   final List<String> options = Arrays.asList("recursive","allFiles","includeDir");
   // This class comes from a package
   final DirScan dirscan = new DirScan(source, options) {
       @Override
       protected Action getResult(final String result) {
           destination.onNext(result);
           return Action.Continue;
       }
   };
   dirscan.scan();
   destination.onComplete();
}

我试过:

    DirScan scanner = mock(DirScan.class);
    when(scanner.scan()).thenReturn("one").thenReturn("two");

那没有用。 我想念什么? 我需要如何重构才能使其可测试?

如果你想用模拟(或间谍)替换dirscan ,你需要重构你的类,它是一个依赖项或参数。 或者,您可以使用PowerMockitowhenNew功能。

让我们假设您更改了您的类,并且您提供DirScan对象作为参数而不是String source 您需要在其他地方为 dirscan 使用某种创建方法(可能是static方法)。

final List<String> options = Arrays.asList("recursive","allFiles","includeDir");

public DirScan createDirScan(String source) {

   // This class comes from a package
   final DirScan dirscan = new DirScan(source, options) {
       @Override
       protected Action getResult(final String result) {
           destination.onNext(result);
           return Action.Continue;
       }
   };

   return dirscan;
}
public void fetchLocalData(final DirScan dirscan, final ObservableEmitter<String> destination) {
    dirscan.scan();
    destination.onComplete();
}

从你的问题来看,你似乎想测试与目标对象的交互,所以你不想模拟dirscan对象(因为如果你这样做就不会有任何交互)。 您可能想要使用spy并仅替换getResult方法。

在您的测试,现在你可以再简单地通过一个spydirscan对象,并确定它与行为thenAnswer

final ObservableEmitter<String> destination = ...

DirScan dirscan = Mockito.spy(createDirScan(source, destination));

Mockito.when(dirscan.getResult(Mockito.any(String.class))).thenAnswer((Answer<Action>) invocation -> {
    String result = invocation.getArgument(0);
    destination.onNext(result);

    return Action.Continue;
});

classUnderTest.fetchLocalData(dirscan, destination);

在这一点上,您可能会注意到最好不要使用间谍,而只使用真正的DirScan对象。 使用spy来做你打算用 overriden 方法做的事情对我来说看起来有点矫枉过正。

真实的物体必须工作才能让这个测试有价值,所以你不妨测试真实的东西。

暂无
暂无

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

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