新しいオブジェクトを作成せずにプライベートメンバオブジェクトをテストする方法

アレックス:

私は、クラスに対するユニットテストを書くことをしようとしています。私は、クラスを変更することはできませんが、私はそれがリフレクションを使用してテストすることも可能だと思います。私はちょうどそれを行う方法がわかりません。ここではクラスがあります:

public class MyClass extends AnotherClass implements TheInterface
{
    private enum SomeTypes
    {
        SAMPLE01, SAMPLE02, SAMPLE03
    }

    private CircularList<SomeTypes> someTypesList; 
    Date date= new Date();
    private SomeOtherClassProcessor01 someOtherClassProcessor01;
    private SomeOtherClassProcessor02 someOtherClassProcessor02;
    private SomeOtherClassProcessor03 someOtherClassProcessor03;

    public Properties initialize (Properties properties) throws Exception
    {
        Properties propertiesToReturn = super.initialize(properties);
        someTypesList = new CircularList<SomeTypes>    (Arrays.asList(SomeTypes.values())); 
        someOtherClassProcessor01 = new SomeOtherClassProcessor01(); 
        someOtherClassProcessor02 = new SomeOtherClassProcessor02(); 
        someOtherClassProcessor03 = new SomeOtherClassProcessor03(); 

        return propertiesToReturn;
    }

    @Override
    public void get(ImportedClass someParams) throws Exception
    {
        SomeTypes types = someTypesList.getFirstAndRotate();

        switch(types)
        {
            case SAMPLE01:
            someOtherClassProcessor01.doSomething(someParams,     date);
            break;
            case SAMPLE02:
            someOtherClassProcessor02.doSomething(someParams,     date);
            break;
            case SAMPLE03:
            someOtherClassProcessor03.doSomething(someParams,     date);
            break;
            default:
            throw new IllegalArgumentException("This " + types + "     was not implemented.");
        }
    }   
}

私のテストでは、これは私がこれまで...ないように注意してください、実際にそれを行う方法を持っているものです。

@RunWith(PowerMockRunner.class)
@PrepareForTest(MyClass.class)
public class TestingMyClass
{
    MyClass mockMyClass;
    SomeOtherClassProcessor01 someOtherClassProcessor01;
    SomeOtherClassProcessor02 someOtherClassProcessor02;
    SomeOtherClassProcessor03 someOtherClassProcessor03;
    Date date;


    @Before
    public void initialize () throws Exception
    {
        mockMyClass = spy(new MyClass()); 
        mockSomeOtherClassProcessor01 =     mock(SomeOtherClassProcessor01.class);
        mockSomeOtherClassProcessor02 =     mock(SomeOtherClassProcessor02.class);
        mockSomeOtherClassProcessor03 =     mock(SomeOtherClassProcessor03.class);
    }

    @Test
    public void testingGet() throws Exception
    {
        date = new Date(); 
        //this is where I'm stuck
        Whitebox.setInternalState(mockMyClass,     "someOtherClassProcessor01", mockSomeOtherClassProcessor01);

    }
}

このためにホワイトボックスを使用することは可能でしょうか?私はそれらのオブジェクトのgetter内部呼び出しがあることを確認する必要があります。私は、ときのような何か試してみてください(someOtherClassProcessor01.doSomethingを(任意の()、日付))。thenReturn(真)?あなたはより多くの詳細が必要な場合は私に知らせてください。

編集:プライベート列挙SomeTypesを模擬することも可能でしょうか?

iluxa:

1つのオプションは、あなたの自身の(嘲笑)の実装を置換することであるSomeOtherClassProcessorMyClassリフレクションを使用しました:

MyClass myClass = new MyClass();
SomeOtherProcessor01 mockProcessor01 = mock(SomeOtherProcessor01.class);

// reflection bit: find the field by its name
// handle NoSuchFieldException
Field someProcessorField = MyClass.getDeclaredField("someOtherProcessor01");
// the field is declared as private, so make it accessible in order to work with it
someProcessorField.setAccessible(true);
// now set your mocked processor into the field. 
// First argument is the object to change; second argument - new value for the field
someProcessorField.set(myClass, mockProcessor01);

PS。PowerMock及び/又は反射を使用することで悪い設計降伏ティモシー当たりとして(:)。あなたは既に十分にテストではありません、それがある場合、あなたは再びそれをテストしようとしてはならないそのコードに依存するべきではありません。あなたは、コードをコントロールしていない場合は、それを修正する方法を-あなたのテストは、実際にバグを明らかにしたと?Javaの11の事になり、反射の使用を禁止していると仮定します。あなたがしているの変更をテストし、フィールドの名前を変更しますコードを仮定-反射して、あなたはコンパイル時の安全性を持っていない...潜在的な問題のリストは続きます

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=332583&siteId=1