1

子コンストラクターの単体テストで、親クラスの機能をモックまたはスタブする方法を探しています。親クラス自体は設計が不十分ですが、契約上の合意により変更できません。既に PowerMockito を使用していますが、PowerMock(EasyMock) も承認済みライブラリのリストに含まれています。単体テストを機能させるためのこれまでの最善の試みとともに、簡略化されたコードを次に示します。

/**
 * The class Parent is locked
 */
public class Parent {

    private final Integer x;
    private final Integer y;

    public Parent(Integer x) {
        this.x = x;
        this.y = loadY();
    }

    private int loadY() {
        // Actual code loads a bunch of stuff from DB
        throw new RuntimeException();
    }

    protected Integer getSum() {
        return x+y;
    }
}

/**
 * This code is not locked, but Child MUST extend Parent and foo MUST be final.
 */
public class Child extends Parent{

    private final Integer foo;

    public Child(int x) {
        super(x);
        foo = getSum();
    }

    public Integer getFoo() {
        return foo;
    }
}

@RunWith(PowerMockRunner.class)
@PrepareForTest({Child.class, Parent.class})
public class ChildTest {

    @Mock
    private Parent par;

    @Test
    public void testGetFoo() throws Exception {

        MemberModifier.suppress(MemberMatcher.constructor(Parent.class, Integer.class));
        PowerMockito.whenNew(MemberMatcher.constructor(Parent.class)).withNoArguments().thenReturn(par);
        Mockito.when(par.loadY()).thenReturn(new Integer(3));
        Mockito.when(par.getSum()).thenReturn(7);

        Child child = new Child(4);

        Assert.assertEquals(new Integer(7), child.getFoo());
    }
}

クラス Child が Parent を拡張し続け、foo が final である限り、クラス Child を編集することはできますし、喜んで行いますが、Parent を編集することは決してできません。getSum() への呼び出しをモックする方が理想的です。これにより、その呼び出しの検証が可能になります (ここでは関係ありませんが、他のシナリオでは可能性があります)。それでも、loadY() のモックや child.y の状態の設定は許容できるようですが、child.foo の設定は正しくないようです。私はこれを理解しようとして Web サイトと Eclipse の間を行ったり来たりして 1 日の大部分を費やしてきましたが、これまでのところ、すべての実行で予想される RTE または NPE が得られています。何か案は?

4

0 に答える 0