使用EasyMock在子类中模拟超类的对象

时间:2016-07-21 10:58:08

标签: java unit-testing powermock easymock

我有一个要测试的课程,如下所示:

public class MainClass extends BaseClass {

    public static int variableToBeAsserted= 0;

    MainClass(ConfigClass config) {
        super(config);
    }

    public void myMethod() {
        List list = objectOfClass1inSuperClass.operation(objectOfClass2inSuperClass.method())
        while(methodInSuperClass()) {
            // doing operations with 'list'
            variableToBeAsserted++;
        }
    }

    // ..few other methods which I am not going to test.
}

我已经压制了BaseClassConfigClass的构造函数。现在我的测试类是这样的:

@RunWith(PowerMockRunner.class)
@PrepareForTest(MainClass.class)
public class TestClass {

    @Before
    public void setUp(){
        suppress(constructor(BaseClass.class))
        suppress(constructor(ConfigClass.class))
    }

    @Test
    public void testMyMethod(){
        MainClass main = new MainClass(new ConfigClass(""));

        List list1= new ArrayList();
        test1.add("somevalues");

        Class1inSuperClass ob1 = PowerMock.createMock(Class1inSuperClass.class);
        Class2inSuperClass ob2 = PowerMock.createMock(Class2inSuperClass.class);

        EasyMock.expect(ob2.method()).andReturn(getClass());
        EasyMock.expect(ob1.operation(getClass())).andReturn(list1);

        PowerMock.replayAll();
        main.myMethod();

        Assert.assertEquals(expectedValue, main.variableToBeAsserted);    
    }
}

现在我不知道为什么,但我的测试用例失败了NullPointerException

它尝试访问objectofClass1inSuperClass并失败。我以为这会嘲笑它。但它不会被嘲笑。

编辑:我只编写测试,我无法更改BaseClass中的任何内容。但是我可以选择修改MainClass

1 个答案:

答案 0 :(得分:0)

您可以通过两种方法将模拟对象注入测试对象。

通过WhiteBox手动

@RunWith(PowerMockRunner.class)
@PrepareForTest(MainClass.class)
public class WhiteBoxApproachTestClass {

  @Before
  public void setUp() throws Exception {
    suppress(constructor(BaseClass.class));
  }


  @Test
  public void testMyMethod() {
    MainClass main = new MainClass(createMock(ConfigClass.class));

    List<String> list1 = new ArrayList<>();
    list1.add("somevalues");

    Class1inSuperClass ob1 = createMock(Class1inSuperClass.class);
    Class2inSuperClass ob2 = createMock(Class2inSuperClass.class);

    expect(ob2.method()).andReturn(getClass());
    expect(ob1.operation(getClass())).andReturn(list1);

    Whitebox.setInternalState(main, "objectOfClass1inSuperClass", ob1);
    Whitebox.setInternalState(main, "objectOfClass2inSuperClass", ob2);

    replayAll();

    main.myMethod();

    assertThat(MainClass.variableToBeAsserted).isEqualTo(5);
  }
}

并通过@TestSubjecthttp://easymock.org/user-guide.html#mocking-annotations

@RunWith(PowerMockRunner.class)
@PrepareForTest(MainClass.class)
public class TestSubjectApproachTestClass {

  @Mock(fieldName = "objectOfClass1inSuperClass")
  private Class1inSuperClass ob1;

  @Mock(fieldName = "objectOfClass2inSuperClass")
  private Class2inSuperClass ob2;

  @TestSubject
  private final MainClass main = new MainClass(createMock(ConfigClass.class));

  @BeforeClass
  public static void before() throws Exception {
    suppress(constructor(BaseClass.class));
  }

  @Test
  public void testMyMethod() {

    List<String> list1= new ArrayList<>();
    list1.add("somevalues");

    expect(ob2.method()).andReturn(getClass());
    expect(ob1.operation(getClass())).andReturn(list1);

    EasyMockSupport.injectMocks(main);

    replayAll();

    main.myMethod();

    assertThat(MainClass.variableToBeAsserted).isEqualTo(5);
  }
}

您可以找到完整代码here