使用Mockito / PowerMockito来模拟超类的公共方法

时间:2018-06-05 11:16:44

标签: java junit mockito junit4 powermockito

Mockito / PowerMockito无论如何都要模拟一些超级类的方法。

下面是一个场景,它执行多级继承。

public class Network {
  public String getNetwork() {
    return "Technology";
  }
}

这是另一个扩展Technology

的课程Network
public class Technology extends Network {
  public Type getTechnology() {
    String network = getNetwork();
    if(network == null){
      return null;
    }
    return network;
  }
}

另一个扩展Service

的班级Technology
public class BaseService extends Technology {
  public void getServices() {
    Type type = getTechnology();
    if(type == null){
      throw new Exception('Type not found');
    }
  }
}

我想为BaseService类方法getServices编写一个测试用例,以便在技术类Type为null时抛出异常。

我尝试过几步但无法帮助。

编写示例测试用例

@Test
    public void test_get_services_should_throw__exception_when_type_is_null() throws Exception{

        //Arrange
        expectedException.expect(Exception.class);

        baseService = Mockito.mock(BaseService.class, Mockito.CALLS_REAL_METHODS);

        when(baseService.getTechnology()).thenReturn(null);


        //Act
        baseService.getServices();
    }

上面的代码段只是一个示例,可能包含错误。如果有的话,请忽略。

请帮我解决此问题。

提前致谢。

3 个答案:

答案 0 :(得分:0)

使用spy对象。这里baseService将成为间谍。

您可以像对spy&#39}那样在mock对象上添加行为。

我会给你一点启发 -

baseService = Mockito.spy(new BaseService());

BTW 如果您赞成composition over inheritance,则无法看到此问题。

答案 1 :(得分:0)

这应该有效。

@RunWith(MockitoJUnitRunner.class)
public class TestInheritance {

  @Spy
  BaseService baseService;

  @Rule
  public final ExpectedException expectedException = ExpectedException.none();

  @Test
  public void test_get_services_should_throw__exception_when_type_is_null() throws Exception{

    expectedException.expect(Exception.class);

    when(baseService.getTechnology()).thenReturn(null);

    baseService.getServices();
  }
}

答案 2 :(得分:0)

正如其他人已经写过的那样,你可以用间谍来做这件事,但我建议采用不同的方法进行测试。

在您非常简单的示例中,所有null - 检查都无关紧要,因为您始终返回一个常量非空值。在那种特殊情况下,根本没有嘲弄的意思。

但是假设你的基类实际上可能有不同的返回值。您应该以这种方式编写测试,而不是模仿父方法,通过改变" state"来触发替代路径。 (班级状态或全局状态,如环境)班级的前提条件。 通过这种方式,您可以创建父行为不同的实际情况。

这将创建一个对更改更加健壮的测试设置(由于重构),并进一步提供第一种形式的集成测试,因为您正在测试您的专业类是否集成 与父类。

针对严格隔离的单元测试可能会导致测试套件无法正确覆盖类之间的协作。严格隔离的测试可能构成了自动化测试方法的基础,但是您应该在某种程度上进行集成测试(不是指这里的"真正的"集成测试,在哪里集成外部服务)。

我的建议是,仅在明确定义的边界(接口)上使用模拟,并尽可能使用真实类,并相应地设计测试(不训练模拟,而是准备前置条件)。