3

次のようなさまざまなクラス階層を考慮した単体テストを作成するための最良のアプローチは何でしょうか。

基本クラスCarと別の基本クラスがありAnimalます。

車には派生クラスVolksWagenとがありFordます。動物には派生クラスDogとがありCatます。

実行時にどの種類のオブジェクトを使用するかを決定するテストをどのように開発しますか。これらのテストがさまざまな階層の何百万ものオブジェクトに適用されることを考えると、コードレプリケーションを使用せずにこれらの種類のテストを実装するための最良のアプローチは何ですか?

これは私の友人に尋ねられたインタビューの質問でした。

4

3 に答える 3

1

私が見ている問題:共通の基本型のn個の派生を検証するために共通のテストを繰り返さないようにしてください。

  • 抽象的なテスト フィクスチャを作成します。ここでは、抽象メソッド GetTestSubject() を使用して、抽象基本クラス (検索用語「抽象テスト フィクスチャ」) 内の基本型 & に対するテストを記述します。この型の派生はメソッドをオーバーライドして、テスト対象の型のインスタンスを返します。したがって、オーバーライドされた単一のメソッドで N 個のサブタイプを記述する必要がありますが、テストは 1 回記述されます。
  • NUnit などの一部の単体テスト フレームワークは、「パラメーター化されたテスト」(検索語) をサポートしています。ここでは、テストを実行する必要があるすべてのオブジェクトを返すメソッド/プロパティを実装する必要があります。次に、実行時にそのような各オブジェクトに対して 1 つまたはすべてのテストを実行します。この方法では、N 個の派生を記述する必要はありません。メソッドは 1 つだけです。
于 2013-02-25T11:21:36.517 に答える
0

実際、単体テストとはMethod Testを指します。単体テストを作成する場合は、作成してテストするメソッドの機能を考え、それをテストするためのクラスとメソッドを作成する必要があります。コードを設計して記述するときにこのアプローチを検討することで、クラスの階層を作成したり、単一のクラスだけを作成したり、その他の任意のタイプの設計を作成したりできます。

ただし、上記のような既存の設計を使用する必要がある場合は、依存オブジェクトに対してInterfacesorを使用Base Classesすることをお勧めします。これにより、これらのクラスを簡単にモックまたはスタブできるためです。

于 2013-02-24T17:02:39.557 に答える
0

これは、私が以前に使用したアプローチの 1 つです (まあ、これの変形です)。

goすべてのクラスをテストしたい Car に何らかの共通メソッド ( )breakDownがあり、サブクラスで異なる動作をする特定のメソッド ( ) があるとします。したがって、次のようになります。

public class Car {
    protected String engineNoise = null;

    public void go() {
        engineNoise = "vroom";
    }

    public void breakDown() {
        engineNoise = null;
    }

    public String getEngineNoise() {
        return engineNoise;
    }
}

public class Volkswagen extends Car {
    public void breakDown() {
        throw new UnsupportedOperationException();
    }
}

次に、次のようにテストを定義できます。

public abstract class CarTest<T extends Car> {
    T car;

    @Before
    public void setUp() {
        car = createCar();
    }

    @Test
    public void testVroom() {
        car.go();
        assertThat( car.getEngineNoise(), is( "vroom" ) );
    }

    @Test
    public void testBreakDown() {
        car.breakDown();
        assertThat( car.getEngineNoise(), is( null ) );
    }

    protected abstract T createCar();
}

ここでVolkswagen、メソッドで何か異なることを行う必要がtestBreakDownあるため、テストが必要な他のメソッドがある可能性があるため、次を使用できますVolkswagenTest

public class VolkswagenTest extends CarTest<Volkswagen> {
    @Test(expected = UnsupportedOperationException.class)
    public void testBreakdown() {
        car.breakDown();
    }

    protected Volkswagen createCar() {
        return new Volkswagen();
    }
}

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

于 2013-02-23T15:16:17.827 に答える