1

単体テストでのリクエスト スコープ管理に関して多くの質問がありましたが、主な回答は、Spring Framework のタスクであり、適切に動作するように注意する必要があるため、スコープ管理をテストしないことです。したがって、たとえば、XML 構成ファイルで要求スコープをスレッドまたはプロトタイプ タイプのスコープに置き換えることをお勧めします。

ほとんどのテストで十分です。登録されていない「リクエスト」スコープについての苦情はなく、テストは正常に実行されています。しかし、それだけでは不十分なケースが 1 つあります。

次のケースを検討してください。

@Component
@Scope("request")
public class MyService {

    @Autowired
    private MyComponent component;

    public void doSomething(String param) {
        component.doTheThing(param);
    }
}

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:my-scope-tweaks.xml"})
public class MyServiceTest {

    @Autowired
    private MyService service;

    @Autowired
    private MyComponent component;

    @Test
    public void test1() {
        service.doSomething("aaa");

        assertEquals("AAA", component.getTheThing());
    }

    @Test
    public void test1() {
        service.doSomething("bbb");

        assertEquals("BBB", component.getTheThing());
    }

}

リクエスト スコープの MyService をテストしたいと考えています。MyComponentもリクエストスコープです。

バリアント A

リクエスト スコープを に置き換えるとSimpleThreadScope、両方のテストで と の同じインスタンスを受け取ることになるMyServiceためMyComponent、たとえば、以前の内部の「ゴミ」が内部に含まれている可能性があるため、test2()から悪い結果を受け取る可能性があります。MyComponenttest1()

バリアント B

MyComponentリクエスト スコープをプロトタイプ スコープに置き換えると、テスト メソッドが異なるインスタンスを受け取るケースが発生するため、MyServiceそれらに対してアサーションを実行できません。

したがって、私が必要とするのは、テスト メソッドに関連するリクエスト スコープのようなものです。リクエスト スコープのすべての Bean は、test1()メソッドの実行中だけ残り、その後破棄されるため、次にtest2()新しく作成されます。

出来ますか?

4

2 に答える 2

0

これはあなたが探しているものではないかもしれませんが、そもそもなぜ Spring を使用してテスト クラスを管理しているのですか? それは私にはやり過ぎのように思えます。単体テストの場合、DI コンテナーは必要ありません。依存関係をモックして、テストしているコンポーネントまたはサービスのカプセル化された機能に注目してください。

ただし、フィールド注入を使用している間は、これを行うことはできません。コンストラクターまたはメソッド インジェクションに変換する必要があります。

于 2012-04-17T16:20:04.237 に答える
0

メソッドに@DirtiesContext. これにより、1 つの単体テストのアプリケーション コンテキストで Bean を操作し、他のものに影響を与えないようにすることができます。

ドキュメンテーション

注釈が付けられたあなたの例@DirtiesContext

@Component
@Scope("request")
public class MyService {

    @Autowired
    private MyComponent component;

    public void doSomething(String param) {
        component.doTheThing(param);
    }
}

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:my-scope-tweaks.xml"})
public class MyServiceTest {

    @Autowired
    private MyService service;

    @Autowired
    private MyComponent component;

    @Test
    @DirtiesContext
    public void test1() {
        service.doSomething("aaa");

        assertEquals("AAA", component.getTheThing());
    }

    @Test
    @DirtiesContext
    public void test2() {
        service.doSomething("bbb");

        assertEquals("BBB", component.getTheThing());
    }

}

クラス内のすべてのテスト メソッドが新しいコンテキストを必要とする場合は、次のようにクラスに注釈を付けることもできます。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:my-scope-tweaks.xml"})
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
public class MyServiceTest {
   //Tests Here...
}
于 2013-11-08T16:54:32.770 に答える