序文
この記事では、ユニットテストにSpringboot+Junit+Mockitoを使用する方法を紹介し、トランザクションに一致するクラスを選択してユニットテストを行う方法を選択します。
単体テストの前に要件を理解してください
優れた単一のテストを作成するには、まず要件を理解する必要があります。何をすべきかを知ることによってのみ、テスト方法を知ることができます。しかし、この記事では、主にMockitoの使用について説明しており、特定のニーズに注意を払う必要はありません。したがって、このセクションでは、特定の要件の説明を省略します。
外部依存関係を分離します
case1。 @Autowiredまたは@Resourceアノテーションによって注釈が付けられた依存関係オブジェクトの返品値を制御する方法テスト済みクラス
テストMatchingServiceImpl.javaのメソッドのマッチング(マッチングオーダー購入、マッチングオーダーセラーオーダー)を例にとる
テストされたクラスMatchingServiceImpl
public class matchingserviceimplを実装しているMatchingservice {private static final logger log = loggerfactory.getLogger(matchingserviceimpl.class); @autowired private quoteservice quoteservice; ... public matchingResultマッチング(マッチングオーダーバイオード、マッチングオーダーセラーオーダー){int currentPrice = quoteService.getCurrentPriceByProduct(buyOrder.getProductCode());一致するresult result = new matchingResult(); if(sellorder!= null && buyOrder!= null && sellorder.getPrice()<= buyOrder.getPrice(){...}}}quoteservice.getCurrentPriceByProduct(buyOrder.getProductCode()); Redisにアクセスして現在の見積もりを取得するには、GetCurrentPriceByProductメソッドの返品値を制御するために、外部依存関係Quoteserviceをmock笑する必要があります。次のように、Mockitoを使用してそれを行うことができます。
クラスMatchingServiceImpltestをテストします
public class matchingserviceimpltest extends mockitobasedtest { / *** @mockでマークされたオブジェクトは、@mockmocks* / @mock private quoteservice quoteserviceによってマークされたオブジェクトに自動的に注入されます。 /** * <pre> * @injectmocksでマークされたテストするオブジェクト、 @mockでマークされたオブジェクトは自動的に注入されます。 *もう1つの注意点は、MatchingserviceImplが直接新しいものであることです(Springコンテナから注入されるのではなく、MatchingServiceImplが新しい(モキト1.9の後に新品でない場合は問題ありません)。ここでは、Spring Container *から他の依存関係を取得する必要はなく、データベース、Redis、Zookeeper、MQを必要としないため、それに直接依存するものは何もないため@test public void testmatching_successwhencurrentpricebetweenebuypriceandsellprice(){matching order buyorder = new matchingOrder(); BuyOrder.SetPrice(1000); BuyOrder.setCount(23); MatchingOrder SellORDER = new MatchingOrder(); sellorder.setprice(800); sellorder.setcount(20); //スタブ(メソッドスタブ)// when(x).thenreturn(y):指定されたメソッドがmockito.when(quoteservice.getcurrentpricebyproduct(mockito.anystring())。 ressult result = matchingservice.matching(buyorder、sellorder); org.junit.assert.assertequals(true、result.issuccess()); //マッチメイキングがorg.junit.assert.assertequals(20、result.gettradecount()); //トランザクション数量org.junit.assert.assertequals(900、result.gettradeprice)をアサートします。 //最新の引用が期待を満たしているかどうかを主張します}ケース2。関数Aがテストされたとき、テスト中のクラスで関数Bの返品値を制御する方法は?
たとえば、MatchingserviceImplには、gettopsellorderや一致など、クラス内の他の関数を呼び出す関数があります。これら2つの関数の返品値を制御する方法は?
ここで解決すべき問題は、実際にクラスの「部分モック」テストクラスの測定された方法(startBuyProcessなど)を実際に実行する方法ですが、他の方法(GetTopsellorderなど)が積み上げられています(実際には実行されていません)。
テストされたクラスMatchingServiceImpl
保護されたvoid startbuyprocess(マッチングオーダーバイオード、boolean waitformatching){while(true){// counterparty mattingordory topsellorder = gettopsellorder(buyOrder.getProductCode());一致するresult matchingResult = matching(buyorder、topsellorder); if(matchingResult.issuccess()){domatchingsuccess(buyOrder、topsellorder、matchingResult、matchingType.buy); if(buyOrder.getCount()<= 0){break; }} else {if(waitformatching){//キューを一致させるように追加するaddtomatchingbuy(buyorder); } else {//注文sendcanclemsg(buyorder); } 壊す; }}}}mockito.spy()を使用すると、「部分的なモック」を達成できます
テストクラスMatchingServiceImpltest.TestStartBuyProcess_IncaseOfMatchingSucs
/*** * *マッチメイキングが成功した後のStartBuyProcessメソッドの処理が期待を満たしているかどうか、つまり、次の判断ブランチを入力した後の動作をテストします * {@link MatchingserviceImpl#startBuyProcess(MatchingOrder、boolean)} * * <pre> * matchingType.Buy); * * if(buyOrder.getCount()<= 0){ * break; *} *} * </ pre> * */ @test public void testStartBuyProcess_incaseofMatchingsuccess(){matching order buyOrder = new MatchingOrder(); BuyOrder.setPrice(700); BuyOrder.setCount(23); // mockito.spy()を使用して、matchingservice matchingservice = mockito.spy(matchingservice)を部分的に枕を枕; MatchingResult firstMatchingResult = new MatchingResult(); firstmatchingResult.setSuccess(true); FirstMatchingResult.setTradeCount(20); MatchingResult secondMatchingResult = new MatchingResult(); SecondMatchingResult.Setsuccess(false); // doreturn(x).when(obj).method()メソッドを積み上げた後、メソッドを積み上げた後、プログラムはこれらのメソッドを実行するときに予想どおりに指定された値を返します。積み上げられていない方法は実行されます。リアルタイムで実行されます。 // 2つのDoreturnsとは、MatchingService.Matchingが最初に呼び出されたときにFirstMatchingResultが返されることを意味します。 .Matching(Mockito.any(MatchingOrder.Class)、Mockito.any(MatchingOrder.Class)); MatchingOrder SellORDER = new MatchingOrder(); sellorder.setprice(600); sellorder.setcount(20); // gettopsellorderメソッドmockito.doreturn(sellorder).when(matchingservice).gettopsellorder(mockito.anystring()); // jedis mockito.when(jedisclient.incrby(mockito.anystring()、mockito.anylong())))に依存する外部メソッドを積み上げます。 // StartBuyProcessはテスト中の関数です。積み上げない場合は、matchingservice.startbuyprocess(buyorder、true); //後続のチェックサムアサーションは、このテストの目的でもあるdomatchingsuccessメソッドの動作をテストすることです。 jedisclient.zremfirstがmockito.verify(jedisclient、mockito.times(1))。zremfirst(mockito.anystring()); org.junit.assert.assertequals(3、buyOrder.getCount()); org.junit.assert.assertequals(0、sellorder.getcount()); }スパイの使用が実証されています。 testStartBuyProcess_incaseofMatchingsuccessからの単体テストの「粒度」について話しましょう。
testStartBuyProcess_incaseofMatchingsuccessの目的は、domatchingsuccessをテストすることです。 domatchingsuccessをテストする前に、以前の準備を完了するために非常に一生懸命働きました。
より良い習慣は、domatchingsuccessを個別にテストするための新しいテスト方法を開始することであり、焦点も集中しています。 domatchingsuccessが上書きされた後、StartBuyProcessは実際に独自の判断の枝をカバーすることができます。カバレッジはまだ達成されており、テストコードの維持が容易になります。 TestStartBuyProcess_IncaseOfMatchingSuccessは、考慮される責任が多すぎるため、変化の影響を容易に受けます。小さなものの変化は、その通常の機能に影響を与える可能性があります。
テストフレームワークMaven依存関係の導入
<Dependency> GroupId> junit </groupid> <artifactid> junit </artifactid> <version> 4.11 </version> <scope> test </scope> </dependency> <dependency> groupid> org.mockito </groupId> <artifactid> mockito-all </artifactid> <バージョン> 1.10.19 </バージョン<scope> test </scope> </dependency> <dependency> groupid> org.springframework </groupid> <artifactid> spring-test </artifactid> <バージョン> 4.2.5.Release </version> <scope> <scope> test </scope> </sependency>
スプリングブート+junit+mockitoのコンテキスト構築
mockitobasedtest
@runwith(springjunit4classrunner.class)@springApplicationConfiguration(classes = testApplication.class)public abstract class mockitobasedtest { @before public void setup()throws excement {// MockitoのAnnotations by the Test Case Case Case MockitoAnloctationsによって発表されたすべてのモックオブジェクトを初期化します。 }} //他のテストクラスはMockitobasedTestを継承します上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。