2

可能重复:
使用 Mockito 测试抽象类

我有一个具有我需要测试的功能的抽象类。我可以在没有抽象方法的操作实现的情况下创建该类的简单派生,但是可以使用模拟框架来完成吗?我需要维护班级内部状态,所以我不能只打电话

mockedInstance = mock(ClassUnderTest.class);

我需要个东西

mockedInstance = spy(new ClassUnderTest(...));

但显然这是不可能的,因为类是抽象的。

4

2 回答 2

2

当我想对一个我不模拟的抽象类进行单元测试时,我是子类。

在其他答案中从 mijer 借用代码

public class MockitoTest {
    public static abstract class MyAbstractClass {
       private int state;
       public abstract int abstractMethod();

       public int method(....)
       {
        ...
       }
    }
}


class Testclass extends MyAbstractClass 
{
      public int abstractMethod()
      {
       ...
      }
 }

然后使用 Testclass 的实例运行您的 MyAbstractClass 测试。您可以控制本地子类中抽象方法的实现。

于 2011-11-17T19:04:56.600 回答
1
import org.junit.Test;
import org.mockito.internal.stubbing.answers.CallsRealMethods;

import static org.mockito.Mockito.*;
import static org.junit.Assert.*;

public class MockitoTest {
    public static abstract class MyAbstractClass {
        private int state;
        public abstract int abstractMethod();
        public void method() {
            System.out.println("method. State: " + (++state));
            System.out.println("abstractMethod: " + abstractMethod());
            anotherMethod();
        }
        public void anotherMethod() {
            System.out.println("anotherMethod. State: " + (++state));
        }
    }

    @Test
    public void test() throws Exception {
        MyAbstractClass obj = mock(MyAbstractClass.class, new CallsRealMethods());
        doReturn(5).when(obj).abstractMethod();

        obj.method();

        verify(obj).abstractMethod();

        assertEquals(2, obj.state);
    }
}

-编辑-

  1. 如果您需要维护您必须使用的对象的内部状态org.mockito.internal.util.reflection.Whitebox.setInternalState,例如:

    @Test
    public void test() throws Exception {
        MyAbstractClass obj = mock(MyAbstractClass.class, new CallsRealMethods());
        setInternalState(obj, "state", 100);
        doReturn(5).when(obj).abstractMethod();
    
        obj.method();
    
        verify(obj).abstractMethod();
        assertEquals(102, obj.state);
    }
    
  2. 如果您要测试的构造函数中有一个具有复杂逻辑的抽象类,则应该扩展该类以仅用于测试或重构您的类,将所有逻辑移至要测试的某个方法。

于 2011-11-17T17:24:07.653 回答