嘲笑抽象类

时间:2011-11-17 17:01:12

标签: java mocking mockito powermock

  

可能重复:
  Using Mockito to test abstract classes

我有一个抽象类,我需要测试一些功能。我可以创建该类的简单派生,而不使用抽象方法的op实现,但是可以使用模拟框架吗?我需要维护类内部状态,所以我不能只调用

mockedInstance = mock(ClassUnderTest.class);

我需要一些东西

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

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

2 个答案:

答案 0 :(得分:2)

当我想对Abstract类进行单元测试时,我没有模拟,我是子类。

在其他答案中借用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的测试。 您可以控制本地子类中抽象方法的实现。

答案 1 :(得分: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. 如果你想在其构造函数中有一个复杂逻辑的抽象类,你应该扩展这个类只是为了测试或重构你的类将所有逻辑移动到一些要测试的方法。