14

Mockito を使用して handleIn() メソッドをテストする必要があります。

ただし、コードは静的メソッドであるこのレガシー コード Util.getContextPDO を呼び出す必要があります。

テスト環境では、この Util.getContextPDO は常に Exception を返すことに注意してください。この Util.getContextPDO() をバイパスして、常にダミーの IPDO を返すつもりです。

public class MyClass {
  public IPDO getIPDO() 
  {
    return Util.getContextPDO(); // note that Util.getContextPDO() is a static, not mockable.
  }

  public String handleIn(Object input) throws Throwable 
  {
    String result = "";
    IPDO pdo = getIPDO();

    // some important business logic.

    return result;
  } 
}

最初は、クラス「MyClass」のspy()を使用してこれを達成できると思っていたので、getIPDO()の戻り値をモックできます。以下は、spy () を使用した私の最初の取り組みです。

@Test
public void testHandleIn() throws Exception
{
    IPDO pdo = new PDODummy();


    MyClass handler = new MyClass ();
    MyClass handler2 = spy(handler);

    when(handler2.getIPDO()).thenReturn(pdo);
    PDOUtil.setPDO(pdo, LogicalFieldEnum.P_TX_CTGY, "test123");
    IPDO pdoNew = handler2.getIPDO();

    Assert.assertEquals("test123,(PDOUtil.getValueAsString(pdoNew, LogicalFieldEnum.P_TX_CTGY)));

}

ただし、when(handler2.getIPDO()).thenReturn(pdo); 回避したい例外をスローしています( handler2.getIPDO() が実際のメソッドを呼び出しているようです)。

コードのこの部分をテストする方法について何か考えはありますか?

4

3 に答える 3

12

テストを次のように変更しました:

@Test
public void testHandleIn() throws Exception
{
  IPDO pdo = new PDODummy();


  MyClass handler = new MyClass ();
  MyClass handler2 = spy(handler);

  doReturn(pdo ).when( handler2 ).getIPDO();
  PDOUtil.setPDO(pdo, LogicalFieldEnum.P_TX_CTGY, "test123");
  IPDO pdoNew = handler2.getIPDO();

  Assert.assertEquals("test123,(PDOUtil.getValueAsString(pdoNew, LogicalFieldEnum.P_TX_CTGY)));

}

効果的なMockitoを読んだ後に解決しました。

于 2012-12-28T06:41:58.530 に答える
12

サードパーティ API で静的呼び出しを取り除くための優れた手法は、静的呼び出しをインターフェイスの背後に隠すことです。

このインターフェースを作成するとしましょう:

interface IPDOFacade {

    IPDO getContextPDO();
}

サードパーティ API で静的メソッドを呼び出すだけのデフォルトの実装があります。

class IPDOFacadeImpl implements IPDOFacade {

    @Override
    public IPDO getContextPDO() {
        return Util.getContextPDO();
    }
}

MyClass次に、サードパーティの API を直接使用するのではなく、インターフェイスへの依存関係を注入してインターフェイスを使用するだけです。

public class MyClass {

    private final IPDOFacade ipdoFacade;

    public MyClass(IPDOFacade ipdoFacade) {
        this.ipdoFacade = ipdoFacade;
    }

    public String handleIn(Object input) throws Throwable
    {
        String result = "";
        IPDO pdo = getIPDO();

        someImportantBusinessLogic(pdo);

        return result;
    }

    ...

}

単体テストでは、独自のインターフェイスを簡単にモックし、好きな方法でスタブして、テスト対象のユニットに挿入できます。

これ

  • プライベート メソッド パッケージをプライベートにする必要がなくなります。
  • 部分的なモックを回避することで、テストを読みやすくします。
  • 制御の反転を適用します。
  • アプリケーションを特定のサードパーティ ライブラリから分離します。
于 2012-12-28T10:04:50.820 に答える