単位テストでのスコープメンバー管理を要求します -- java フィールド と spring フィールド と unit-testing フィールド と junit フィールド と scope フィールド 関連 問題

Request scope bean management in Unit Tests


1
vote

問題

日本語

ユニットテストでのリクエストスコープ管理に関する質問が多数あり、主に答えはSpring Frameworkタスクとしてスコープ管理をテストしないことであり、それが正しく機能するように注意する必要があります。したがって、アドバイスは、XML構成ファイル内のリクエストスコープをスレッドまたはプロトタイプタイプのスコープに置き換えることです。

ほとんどのテストで十分な場合、登録されていない「リクエスト」スコープとテストは正常に実行されていません。しかし、私はそれが十分ではないケースを持っています。

次の場合を検討してください。

<事前> <コード> @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() は、前の<コード> test1()

から内部の "Trash"を内部に含めることができるため、<コード> MyComponent からの悪い結果を受け取ることができます。

変種B

プロトタイプスコープにリクエストスコープを置き換えた場合 - テストメソッドが<コード> MyComponent の異なるインスタンスを受信して​​いる場合は、 @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()); } } 0 は実行できません。それらの主張

だから私が必要とするのは、 @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()); } } 1 メソッドの間にすべてのリクエストスコープBeanが残り、次の @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()); } } 2 それらは再び新たに作成されます。

それは可能ですか?

英語

There have been many questions regarding request scoped management in unit tests and mainly answer is to do not test the scope management, as its a Spring Framework task and it should take care that it works properly. So advice, for example, would be to replace the request scope with thread or prototype type scope in the XML configuration file.

For most of the tests its enough, there are no complaints about not registered "request" scope and tests are running fine. But I do have one case where it is not enough.

Consider following case:

@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());     }  } 

I want to test MyService, which is request-scoped. MyComponent is request scope as well.

Variant A

If I replace the request scope with SimpleThreadScope, then in by both tests I would receive the same instance of MyService and MyComponent, so for example test2() could receive bad results from MyComponent as it could internally contain some internal "trash" from previous test1()

Variant B

If I replace request scope with prototype scope - I would get the case where my test methods are receiving different instances of MyComponent as MyService does - so I cannot perform any assertions on them.

So what I would need is kind of test method-related request scope, where all request-scoped beans remain just during the test1() method and then gets destroyed, so within next test2() they would be created newly again.

Is it possible?

</div
              

回答リスト

0
 
vote

これはあなたが探しているものではないかもしれませんが、そもそもテストクラスを管理するためにSpringを使用しているのはなぜですか?それは私に溢れているようです。ユニットテストの場合は、DIコンテナを必要としません。テストしているコンポーネントまたはサービスのカプセル化された機能に依存して依存して焦点を合わせるだけです。

フィールド注射を使用しながら、それをすることはできません。コンストラクタまたはメソッドの注入に変換する必要があります。

 

This may not be what you're looking for, but why are you using Spring to manage your test classes in the first place? That seems like overkill to me. For unit testing, you shouldn't need a DI container. Just mock the dependencies and focus on the encapsulated functionality of the Component or Service you're testing.

You won't be able to do that, though, while using field injection. You'll need to convert to constructor or method injection.

</div
 
 
       
       
0
 
vote

@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... }
 

It is possible to receive a new context for every method in your unit test by annotating the method with @DirtiesContext. This allows you to manipulate beans in the application context for one unit test and not have it affect the others.

Documentation

Your example annotated with @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());     }  } 

If all of your test methods within your class require a new context you can also just annotate the class as follows:

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({"classpath:my-scope-tweaks.xml"}) @DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD) public class MyServiceTest {    //Tests Here... } 
</div
 
 

関連する質問

0  C ++の客観的C範囲外  ( Objective c in c out of scope ) 
WOSCLIBにはほとんど問題がありません。特にライブラリではなく、コールバック関数です。特定のOSCコマンドを聴くのは、のようなコールバックメソッドを登録する必要があります。 <事前> <コード> void TheOscStartMethod::Metho...

0  `let`なしでローカル変数を作成できますか?  ( Can you create local variables without a let ) 
EG1 - <コード> let を使用して <コード> (defun demo1 () (let ((a 1) (b 2)) ; these print fine (print a) (print b))) (demo1...

12  CDIとJavaのコンテキストとスコープの違いはまったく  ( The difference between context and scope in cdi and java at all ) 
JSR-299の検討、 SCOPESがCDIでどのように機能するかを説明します。どうやら、コンテキストはスコープに密接に関連している概念です。私はそれぞれが何であるかについて少し理解しましたが、それは私の心の中ではあまり明確に分離されていません、そして私は互...

6  ループ中の可変スコープ  ( Variable scope inside while loop ) 
これは私が今までに遭遇した最も奇妙なことの一つです。私はcでは多くのプログラムしませんが、私が真実であることを知っていることから、さまざまな情報源であることから、変数 macroname 、 macrobody のみがしばらくのループの範囲でのみ定義されます。...

0  私のワークフローサービス(4.0)変数がDowhileアクティビティでNULLになるのはなぜですか?  ( Why does my workflow service 4 0 variable go null in a dowhile activity ) 
私は私が「購読」と「購読解除」にアクティビティを設定しようとしているWFサービスを持っています。私はこのWF永続的なデュプレックスチュートリアルは、私のサービスがクライアントにコールバックを実行しているためです。基本的に、チャットサービスと考えています。 私は...

0  ユーザーがGet Paramsを介して名前付きスコープを選択できるようにします。  ( Allow the user to pick a named scope via get params ) 
私の投稿モデルでは、私は名前付きスコープを持っています: <事前> <コード> named_scope :random, :order => "Random()" f=1.00001 を使用してGETリクエストを送信することで、ランダムな順序で投稿を取...

1  jQueryプラグインの変数  ( Jquery plugin variables ) 
次のコード <前> (機能($){ //カルーセル var carousel = { 設定: { ItemperPage:1、 ItemperTransition:1、 ...

7  JSF 2.0:私のビュースコープBeanがまだ同じビューでも再作成されるのは[複製]  ( Jsf 2 0 why my viewscope beans is re created even though still on same view ) 
この質問はすでにここで答えを持っています @ViewScoped Calls @PostConstruct (1回) ...

-1  ['$ scope)の横にある[' $ scope)を持っていることの違いは、['$ scope' 'を持っていません  ( What is the difference of having scope next to functionscope to doesnt h ) 
この2つのコードの違いは何ですか? <事前> <コード> var myApp = angular.module('myApp', []); myApp.controller('GreetingCtrl', function($scope) { $sc...

2  C ++の再構文を再構築します  ( Understanding c reconstruct syntax ) 
作成後にオブジェクトのコンストラクターを再度呼び出すことができますか? <事前> <コード> Address9 ...

4  検証チェックを行うためにSpring @Autowiredプロセスを傍受できますか?  ( Can i intercept spring autowired process to do validation checks ) 
コードと @Autowired プロトタイプスコープBeanに間違いを犯すことがあります。シングルトンは、それがまるでシングルトンでもあるかのようにその依存性を使用することになるので、これは間違っています。 これを検出してエラーを発生させるために自動化/ DI...

1  クラス内の名前空間の優れた代替手段は何ですか?  ( What is a good alternative to namespaces within classes ) 
問題はC ++であるとクラス内の名前空間宣言を許可していません。(インターネットで検索し、これを見つけました。それが本当でない場合は、それを言ってください) コンテキスト:マイクラスには列挙があります。 <事前> <コード> class GameCharact...

1  可変値は関数を越えて更新されません  ( Variable values not being updated across functions ) 
変数<コード> Message とブール値<コード> count from関数 validator は、<コード> inputFocus を実行すると更新されません。関数。そのため、<コード> validator は常にtrueを返します。 <事前> <コー...

0  PHP:グローバル関数から囲まれたスコープへのアクセス  ( Php accessing enclosed scopes from global functions ) 
私はいくつかのPHPコードで頭を傷つけます。 PHPが非常に新しいように、構文エラーのためにまだ実行されないため、まだ動作しているのかわかりません。<コード> 99887663 構文エラーは、PHPバージョンを完全にサポートしているにもかかわらず、<コード...

2  JavaScript変数スコープ  ( Javascript variable scope ) 
<コード> App.site.profile ?から<コード> selectCompanyJump(this) を内部的に呼び出すことは可能です。 App.site.profile.selectStateJump(this); を行うのではなく、 pare...

8  VI / Vimの検索スコープを制限する方法  ( How to limit the search scope in vi vim ) 
検索と交換範囲は次のように制限されることができます: <事前> <コード> :16,256s/search_term/replacement/gc 私の検索語を他のテキストと置き換えたくない、私はそれらを見つけたいだけです。私は以下を試しました、しかしそれ...

2  Python:スコープ内の長い変数名を予防するにはどうすればよいですか  ( Python how do i prevent long variable names in scope ) 
私はそのようなものがあります: self.megacity.ResourceLoader.Sound.mcintro.play() このような長いものを防ぐためのエレガントな方法はありますか? ある種の構造的変化、おそらく? ありがとう。 ...

0  フラッシュアクションスクリプト3可変スコープが機能しない  ( Flash action script 3 variable scope not working ) 
いくつかのクラスから別のクラスにいくつかの変数を渡したいが、以下のコードは機能していない。 <事前> <コード> package a { public class a { public var a_var:String; public va...

69  vb.netプロパティ - パブリックGet、Private Set  ( Vb net properties public get private set ) 
私は私が尋ねるだろう...しかし、プロパティの一部を公開として入手できるようにする方法はありますが、セットをプライベートに保ちますか? それ以外の場合私は2つのプロパティやプロパティとメソッドが必要なと思っています。これはクリーナーになるでしょう。 ...

67  externとconstを混在させる  ( Mixing extern and const ) 
extern const として、externとconstをミックスできますか?もしそうであれば、 const 修飾子はそれが宣言されている範囲内でのみ統治を課すか、それが宣言されている翻訳ユニットの宣言に正確に一致するべきですか? NS。実際の i がc...

0  Rails:スコープの方法  ( Rails methods in scopes ) 
私のモデルの1つに次の方法があります: <事前> <コード> def remaining_stock if initial_stock initial_stock - bought_items else 0 ...

41  Pythonスコープ: "UnboundLocalError:local変数 'c​​' applicationの前に参照されます" [duplicate]  ( Python scope unboundlocalerror local variable c referenced before assignmen ) 
この質問はすでにここで回答を持っています (8回答) 閉じる 6年前> 私はこれを理解しようとしています...

0  アレイスコープの問題  ( Array scope issue ) 
私は何時間も見回していて、私は正直にこれが機能していない理由を理解していません。私は範囲を理解していましたが、これが.popularメソッドに関するコールバックと関係があると思います。任意のアドバイス? <事前> <コード> Class17 ...

1  PHP JavaScript - <script> </ script>タグ内のPHP変数の範囲は何ですか?  ( Php with javascript what is the scope of php variables inside a script scri ) 
ページロード時にJavaScriptがいくつかのPHP変数にアクセスする必要があるため、PHPとJavaScriptをミックスしようとしています。私は何かを理解するのに苦労しています、そして私はコード例を作りました。 <事前> <コード> <?php sess...

0  参照によってベクトルを渡すが、変更はC ++を貼り付けることはできません  ( Passing vector by reference but alterations wont stick c ) 
<事前> <コード> void RemoveGreenEffect::processImage(vector<Point>& points) { for (int i = 0; i < points.size(); ++i) { ...

関連する質問

0  C ++の客観的C範囲外 
0  `let`なしでローカル変数を作成できますか? 
12  CDIとJavaのコンテキストとスコープの違いはまったく 
6  ループ中の可変スコープ 
0  私のワークフローサービス(4.0)変数がDowhileアクティビティでNULLになるのはなぜですか? 
0  ユーザーがGet Paramsを介して名前付きスコープを選択できるようにします。 
1  jQueryプラグインの変数 
7  JSF 2.0:私のビュースコープBeanがまだ同じビューでも再作成されるのは[複製] 
-1  ['$ scope)の横にある[' $ scope)を持っていることの違いは、['$ scope' 'を持っていません 
2  C ++の再構文を再構築します 
4  検証チェックを行うためにSpring @Autowiredプロセスを傍受できますか? 
1  クラス内の名前空間の優れた代替手段は何ですか? 
1  可変値は関数を越えて更新されません 
0  PHP:グローバル関数から囲まれたスコープへのアクセス 
2  JavaScript変数スコープ 
8  VI / Vimの検索スコープを制限する方法 
2  Python:スコープ内の長い変数名を予防するにはどうすればよいですか 
0  フラッシュアクションスクリプト3可変スコープが機能しない 
69  vb.netプロパティ - パブリックGet、Private Set 
67  externとconstを混在させる 
0  Rails:スコープの方法 
41  Pythonスコープ: "UnboundLocalError:local変数 'c​​' applicationの前に参照されます" [duplicate] 
0  アレイスコープの問題 
1  PHP JavaScript - <script> </ script>タグ内のPHP変数の範囲は何ですか? 
0  参照によってベクトルを渡すが、変更はC ++を貼り付けることはできません