首页 > 解决方案 > Mockito Mock 依赖项的超类方法

问题描述

我有一个这样的依赖类:

public class Subject {
   private Dependency dep;

   public Subject(Dependency d) {
     this.dep = d;
   }

   public Result test() {
     return dep.validate(); 
   }
}

我的依赖类实际上是一个基类。它看起来像这样:

public Class Dependency extends Base {
   void method1() {

   }

}

Base 类是一个抽象类,如下所示:

public abstract class Base {
  protected abstract method1() {
  }

  //This is the method I want to mock
  public Result validate() {
  }
}

现在,我正在尝试测试我的课程Subject

public class SubjectTest {
  @Mock
  private Dependency dep;

  private Subject subject;

  @Before
  public void setup() {
   initMocks(this);
   subject = new Subject(dep);
  }

  @Test
  public void test() {
    when(dep.validate()).thenReturn(Result.VALID);  //validate is a super class method

    subject.test();
  }
}

当我尝试在 中模拟该方法时when(dep.validate()).thenReturn(Result.VALID),它实际上调用了真正的超类方法并抛出了 NullPointerException。

我该如何解决这个问题?我知道组合比继承更受青睐,但我无法控制 Dependency 类。所以,我不能去改变它。

我的团队也不赞成使用 PowerMockito。所以,我也不能使用它。

标签: javaunit-testingmockito

解决方案


可能你在设置中搞砸了。我试图重现您的案例,它适用于我的设置:

package com.example.demo;

import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Mockito.when;

enum Result {
    VALID, INVALID;
}
abstract class Base {
    protected abstract void method1();

    public Result validate() {
        return Result.INVALID;
    }
}
class Dependency extends Base {
    public void method1() {

    }
}
class Subject {
    private Dependency dep;

    public Subject(Dependency d) {
        this.dep = d;
    }

    public Result test() {
        return dep.validate();
    }
}

public class SampleTest {

    private Dependency dep = Mockito.mock(Dependency.class);

    private Subject subject;


    @Test
    public void testMe() {
        subject = new Subject(dep);
        when(dep.validate()).thenReturn(Result.VALID);  //validate is a super class method

        Result result = subject.test();
        assertThat(result, equalTo(Result.VALID));
    }

}

总而言之,Mockito 应该毫无问题地支持这样的用例。

我怀疑它带有“initMocks”/ 或者@Mock如果您使用的是 JUnit 5 可能需要特殊运行器/扩展的注释,这在问题中没有显示。

在上面的示例中,我有意避免使用这些“高级”功能,以创建一个最小的可重现示例。请检查此代码并更新它是否适合您。

PS:使用 Mockito-core:3.3.3 进行测试


推荐阅读