7

この素晴らしい回答で詳しく説明されているように、Mockito を使用して抽象クラスを単体テストしたいと思います。

秘訣は、抽象クラスがそのコンストラクターに注入される戦略に依存していることです。戦略のモックを作成しました。モックされた BaseClass のインスタンスで、モックされた戦略を単体テストに使用したいと考えています。

これをどのように配線できるかについての提案はありますか? 私は現在 IoC フレームワークを使用していませんが、Spring を検討しています。おそらくそれはトリックを行うでしょうか?

// abstract class to be tested w/ mock instance
abstract BaseClass
{
    // Strategy gets mocked too 
    protected BaseClass( Strategy strategy)
    {
        ...
    }
}

更新:
Mockito メーリング リストによると、現在、モックのコンストラクターに引数を渡す方法はありません。

4

3 に答える 3

6

次のように、リフレクションを使用して基本クラスにプライベートフィールドを設定するだけになりました。

// mock the strategy dependency
Strategy strategyMock = mock( Strategy.class);
when(....).thenReturn(...);

// mock the abstract base class
BaseClass baseMock = mock(BaseClass.class, CALLS_REAL_METHODS);

// get the private streategy field
Field strategyField = baseMock.getClass().getSuperclass().getDeclaredField("_privateStrategy");

// make remove final modifier and make field accessible
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(strategyField, strategyField.getModifiers() & ~Modifier.FINAL);          
strategyField.setAccessible(true);

// set the strategy
strategyField.set(baseMock, strategyMock);

// do unit tests with baseMock
...

プライベート フィールドの名前が変わると壊れてしまいますが、コメントが付けられているので、私はそれを受け入れることができます。シンプルで、1 行のコードであり、セッターを公開したり、テストで明示的にサブクラス化したりするよりも、これが望ましいと思います。

編集: 私のプライベートフィールドは「最終」である必要があり、回避するには追加のリフレクションコードが必要だったため、もはや1行のコードではありません。

于 2012-04-17T16:16:43.730 に答える
5

春のコンテキストレベルでMockitoを使用して、この種のことが行われるのを見てきました。

例えば:

<bean id="myStrategy" name="myStrategy" class="org.mockito.Mockito" factory-method="mock">
    <constructor-arg value="Strategy" />
</bean>

それが役立つことを願っています。

于 2012-04-16T22:15:45.640 に答える
0

特別なことをする必要はありません。通常のようにBeanをモックするだけです。

Bean bean = mock(Bean.class); 
when(bean.process()).thenReturn(somethingThatShouldBeNamedVO);

うまくいきます:)

于 2012-04-17T12:30:03.730 に答える