7

私は読んClean Code: A Handbook of Agile Software Craftsmanshipでいて、例の1つにPortfolioクラスとクラスが含まれていTokyoStockExchangeます。ただし、ポートフォリオの値を決定するために外部 API としてPortfolio依存しているため、非常にテスト可能ではありません。これは非常に揮発性のルックアップであり、テストを助長しません。TokyoStockExchange

したがって、彼らは共通のStockExchangeインターフェースを作成することでこれを解決し、基本クラスTokyoStockExchangeを実装しています。DummyStockExchangeしたがって、依存関係逆転の原則が達成され、PortfolioTestクラスで をインスタンス化しDummyStockExchange、株価を企業に固定し、DummyStockExchangeインスタンスをポートフォリオに割り当て、その企業の株式をポートフォリオに追加し、期待値がまさに適正値。コードは次のとおりです。

public class PortfolioTest
{
    private DummyStockExchange exchange;
    private Portfolio portfolio;

    protected void setUp()
    {
        exchange = new DummyStockExchange();
        exchange.fix("MSFT", 100);
        portfolio = new Portfolio(exchange);
    }

    public void GivenFiveMSFTTotalShouldBe500()
    {
        portfolio.add(5, "MSFT");
        Assert.assertEquals(500, portfolio.value());
    }
}

私の質問は、単純に、なぜですか?

TokyoStockExchangeクラスがクラスと連携して機能するかどうかをテストしようとしていましたPortfolio。明らかに、株価を設定する新しいメソッドを使用して別のクラスを作成し、ポートフォリオにそれらの株式を 5 つ与えると、すべてが機能します。それはただ..テストするのは役に立たないようです。TokyoStockExchange株価が変動するため、基本的にテストが不可能であることは理解してPortfolioいますが、役に立たないテストでのサブビングが状況にどのように役立つかはわかりません。

加算器プログラムが機能するかどうかわからないのと同じように見えますが、利用可能な唯一の数値はランダムに生成されるため、2 を与えるダミー クラスを作成し、if をテストします2 + 2 = 4。ええ、明らかにそれは本当です。TokyoStockExchange別のクラスをテストしているため、中断することはできますが、テストは成功します。いずれにせよ、これはすべて欺瞞のように思えます。また、機能することがわかっているものをテストするためだけに追加のコードを書かなければならないという結果にもなります。

これが、現時点で単体テストを理解する上での最大の問題だと思います。私は自分が間違っていることを知っています。うまくいけば、誰かが私を助けてくれます。

4

2 に答える 2

7

Portfolioアイデアは、クラス内のロジックを から分離してテストしたいということですTokyoStockExchange。Moq や Rhino Mocks などのモック フレームワークを使用すると、さまざまな出力と動作を簡単にシミュレートしTokyoStockExchange、ユニット テストを記述して、Portfolio正しく応答することを確認できます。クラスに対して個別の単体テストを作成しますTokyoStockExchange

これは、2 つのクラス間の統合テストが必要ないと言っているわけではありません。モック オブジェクトを使用せずにすべてのシナリオを適切に検証することは困難です。

例としてこのような単純なクラスで値を理解するのは難しいですが、「ライブ」クラスで配置するのが難しい、または不可能な状況のテスト ケースを検証する必要があるより複雑なクラスを考えると、単体テストははるかに多くなります。重要。

于 2012-08-17T02:18:22.490 に答える
3

実行する必要があるテストには、単体テストと統合テストの 2 種類があります。

単体テストは、コードのすべての単位を個別にテストするホワイト ボックス テストであると想定されています。通常、これは各クラスのパブリック インターフェイスを指します。既知のデータ セットが与えられた場合に、ユニットが予測可能な結果を​​返すことが保証されるように、それらの依存関係をモック化します。

単体テストで「明らかにすべてが機能する」と言います。これは、コードにバグがないことを前提としています。その仮定を立てることができれば、そもそも何もテストする必要はありません! また、すべてを単体テストする必要はありません。API メソッドを呼び出して結果を渡すPortfolio薄い層にすぎStockExchangeない場合は、わざわざ単体テストを行うべきではありません。

一方、Portfolio実際のロジックが含まれている場合は、それを単体テストする必要があります。からデータを取得し、データを分析し、価格が急速に下落し始めた場合など、株価に何らかの異常が見られた場合にアラート メッセージをユーザーに送信するPortfolioメソッドがあるとします。Stock Exchange予想される条件下でアラートが実際にトリガーされて送信されることを確認したいでしょうが、じっと座って次の株式市場の暴落を待ちたいとは思わないでしょう。したがって、単体テストではStock Exchange、アラートをトリガーしたい種類の値を生成するモックを作成し、それが実際に発生することを確認します。ある場合は素晴らしいですが、そうでない場合は、バグを見つけただけです。

統合テストは、2 つのユニットを連携してテストするものであり、これも重要です。しかし、統合テストで特定の種類のシナリオをシミュレートすることはより困難であり、バグが実際にどこに隠れているかを把握するのにはあまり役に立ちません。アプリケーションの統合テストを実行したところ、アラートが送信されるべきときに送信されていないことが判明した場合、どこに問題があるのでしょうか? サードパーティ API にバグはありますか? 証券取引所はあなたに悪い値を送信していますか? 警告システムが間違ったアドレスにメッセージを送信していませんか? 分析方法に問題があったことがわかるまで、しばらく時間がかかる場合があります。

于 2012-08-17T02:49:44.247 に答える