【问题标题】:Mock object of super class in subclass using EasyMock使用 EasyMock 在子类中模拟超类的对象
【发布时间】:2016-07-21 10:58:08
【问题描述】:

我有一个要测试的类是这样的:

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

【问题讨论】:

  • 如果我错了,请纠正我。这就是我对您的情况的理解:在BaseClass 的构造函数中,objectOfClass1inSuperClassobjectOfClass2inSuperClass 字段被初始化。您抑制构造函数BaseClass 以避免这种行为。但是为什么要压制ConfigClassconstructor?我还看到您创建了模拟,但从不注入/设置它。
  • 即使configClass 构造函数也会初始化一些我不想使用的类。因此,我正在压制它。是的,这就是我想知道的。如何在我的实际对象中注入模拟

标签: java unit-testing powermock easymock


【解决方案1】:

您有两种方法可以将模拟对象注入到被测对象中。

手动通过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);
  }
}

通过@TestSubject (http://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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多