Junit 使用Mock测试函数

Junit 使用Mock测试函数,junit,mocking,mockito,Junit,Mocking,Mockito,我想测试一个函数,其中包含对另一个函数的调用(它接受两个参数) 我想模拟那个内部函数,但我很难把什么作为参数传递 void func(classA a,classB b) { List<ClassC> list= Objd.func2(a.getSome(),b) ///some other things } 但它不起作用,func2执行 我甚至试过 InterfaceClassD objD=Mockito.mock(InterfaceClassD.class) Mockito.w

我想测试一个函数,其中包含对另一个函数的调用(它接受两个参数) 我想模拟那个内部函数,但我很难把什么作为参数传递

void func(classA a,classB b)
{
List<ClassC> list= Objd.func2(a.getSome(),b)
///some other things
}
但它不起作用,func2执行

我甚至试过

InterfaceClassD objD=Mockito.mock(InterfaceClassD.class)
Mockito.when(obj.func2(anyList(),any(classB.class)).thenreturn(null);
注意-a.getSome()返回列表
但是它也不起作用,func2执行

如果没有更多的上下文,很难回答这个问题

在函数“func”中,对“Objd”的引用来自何处?在哪里申报

在测试中创建和使用模拟有两个步骤:

  • 创建模拟
  • 注射模拟
  • “注入模拟”是指(以某种方式)将函数将使用的真实对象的引用替换为使用Mockito创建的模拟版本

    例如:

    // Class under test
    public class Foo {
      // this is the object we need to mock
      private InterfaceClassD objD;
    
      void func(classA a,classB b) {
        // here is where we use "objD"
        List<ClassC> list= objD.func2(a.getSome(),b)
        ///some other things
      }
    }
    
    //测试中的类
    公开课Foo{
    //这是我们需要模仿的对象
    专用接口CLASSD objD;
    无效函数(a类、b类){
    //这里是我们使用“objD”的地方
    List List=objD.func2(a.getSome(),b)
    ///其他一些事情
    }
    }
    
    为了用mock objD编写测试,您必须在调用正在测试的方法(函数)之前用mock替换“真实”objD

    通常通过构造函数注入、setter注入或Mockito注释来完成

    构造函数注入示例:

    // Class under test
    public class Foo {
      // this is the object we need to mock
      private InterfaceClassD objD;
    
      // constructor injection
      public Foo(InterfaceClassD objD) {
        this.objD = objD;
      }
    
      void func(classA a,classB b) {
        // here is where we use "objD"
        List<ClassC> list= objD.func2(a.getSome(),b);
    
        ///some other things
      }
    }
    
    // Unit test
    public class FooTest {
      @Test
      public void someTest() {
        // create the mock:
        InterfaceClassD mock = Mockito.mock(InterfaceClassD.class);
    
        // inject the mock:
        Foo foo = new Foo(objD);
    
        // test: this should call method func but use the mock
        foo.func(dummyA, dummyB);
    
        // verify/assert something...
      }
    }
    
    // Class under test
    public class Foo {
      // this is the object we need to mock
      private InterfaceClassD objD;
    
      // setter injection
      public void setInterfaceClassD(InterfaceClassD objD) {
        this.objD = objD;
      }
    
      void func(classA a,classB b) {
        // here is where we use "objD"
        List<ClassC> list= objD.func2(a.getSome(),b);
    
        ///some other things
      }
    }
    
    // Unit test
    public class FooTest {
      @Test
      public void someTest() {
        // create the mock:
        InterfaceClassD mock = Mockito.mock(InterfaceClassD.class);
    
        Foo foo = new Foo();
        // inject the mock:
        foo.setInterfaceClassD(mock);
    
        // test: this should call method func but use the mock
        foo.func(dummyA, dummyB);
    
        // verify/assert something...
      }
    }
    
    //测试中的类
    公开课Foo{
    //这是我们需要模仿的对象
    专用接口CLASSD objD;
    //构造函数注入
    公共Foo(接口类objD){
    this.objD=objD;
    }
    无效函数(a类、b类){
    //这里是我们使用“objD”的地方
    List List=objD.func2(a.getSome(),b);
    ///其他一些事情
    }
    }
    //单元测试
    公务舱{
    @试验
    公共测试(){
    //创建模拟:
    InterfaceClassD mock=Mockito.mock(InterfaceClassD.class);
    //注入模拟:
    Foo-Foo=新的Foo(objD);
    //测试:这应该调用func方法,但使用mock
    foo.func(dummyA,dummyB);
    //验证/断言某事。。。
    }
    }
    
    使用setter注入的示例:

    // Class under test
    public class Foo {
      // this is the object we need to mock
      private InterfaceClassD objD;
    
      // constructor injection
      public Foo(InterfaceClassD objD) {
        this.objD = objD;
      }
    
      void func(classA a,classB b) {
        // here is where we use "objD"
        List<ClassC> list= objD.func2(a.getSome(),b);
    
        ///some other things
      }
    }
    
    // Unit test
    public class FooTest {
      @Test
      public void someTest() {
        // create the mock:
        InterfaceClassD mock = Mockito.mock(InterfaceClassD.class);
    
        // inject the mock:
        Foo foo = new Foo(objD);
    
        // test: this should call method func but use the mock
        foo.func(dummyA, dummyB);
    
        // verify/assert something...
      }
    }
    
    // Class under test
    public class Foo {
      // this is the object we need to mock
      private InterfaceClassD objD;
    
      // setter injection
      public void setInterfaceClassD(InterfaceClassD objD) {
        this.objD = objD;
      }
    
      void func(classA a,classB b) {
        // here is where we use "objD"
        List<ClassC> list= objD.func2(a.getSome(),b);
    
        ///some other things
      }
    }
    
    // Unit test
    public class FooTest {
      @Test
      public void someTest() {
        // create the mock:
        InterfaceClassD mock = Mockito.mock(InterfaceClassD.class);
    
        Foo foo = new Foo();
        // inject the mock:
        foo.setInterfaceClassD(mock);
    
        // test: this should call method func but use the mock
        foo.func(dummyA, dummyB);
    
        // verify/assert something...
      }
    }
    
    //测试中的类
    公开课Foo{
    //这是我们需要模仿的对象
    专用接口CLASSD objD;
    //塞特注射
    公共无效setInterfaceClassD(InterfaceClassD objD){
    this.objD=objD;
    }
    无效函数(a类、b类){
    //这里是我们使用“objD”的地方
    List List=objD.func2(a.getSome(),b);
    ///其他一些事情
    }
    }
    //单元测试
    公务舱{
    @试验
    公共测试(){
    //创建模拟:
    InterfaceClassD mock=Mockito.mock(InterfaceClassD.class);
    Foo-Foo=新的Foo();
    //注入模拟:
    foo.setInterfaceClassD(模拟);
    //测试:这应该调用func方法,但使用mock
    foo.func(dummyA,dummyB);
    //验证/断言某事。。。
    }
    }
    
    使用Mockito注释和JUnit 5的示例:

    // Class under test
    public class Foo {
      // this is the object we need to mock
      private InterfaceClassD objD;
    
      void func(classA a,classB b) {
        // here is where we use "objD"
        List<ClassC> list= objD.func2(a.getSome(),b);
    
        ///some other things
      }
    }
    
    // Unit test
    // Note the Mockito extension annotation.
    @ExtendWith(MockitoExtension.class)
    public class FooTest {
      // the Mockito JUnit extension will instantiate this automagically.
      // The name of the mock must exactly match the name of the field in
      // containing class.
      private @Mock InterfaceClassD objD;
    
      // Mockito annotation processing will create an instance of Foo, and
      // replace any of its fields with any mocks that have the same name
      // and type. In this case, objD.
      private @InjectMocks Foo foo;
    
      @Test
      public void someTest() {
        // Just use it.
        // test: this should call method func but use the mock
        foo.func(dummyA, dummyB);
    
        // verify/assert something...
      }
    }
    
    
    //测试中的类
    公开课Foo{
    //这是我们需要模仿的对象
    专用接口CLASSD objD;
    无效函数(a类、b类){
    //这里是我们使用“objD”的地方
    List List=objD.func2(a.getSome(),b);
    ///其他一些事情
    }
    }
    //单元测试
    //注意Mockito扩展注释。
    @ExtendWith(MockitoExtension.class)
    公务舱{
    //Mockito JUnit扩展将自动实例化这个。
    //模拟的名称必须与中字段的名称完全匹配
    //包含类。
    private@Mock InterfaceClassD objD;
    //Mockito注释处理将创建一个Foo实例,并且
    //将其任何字段替换为具有相同名称的任何模拟
    //和类型。在本例中,为objD。
    private@mocks-Foo-Foo;
    @试验
    公共测试(){
    //就用它吧。
    //测试:这应该调用func方法,但使用mock
    foo.func(dummyA,dummyB);
    //验证/断言某事。。。
    }
    }
    
    <代码> >代码>函数2> /COD> <代码> Objd < /代码>类中的静态方法?不,它不是静态方法。您可以认为Objd是类的对象。