こんにちは、私の知る限り、テスト分離はSAP内部でユニットテストコードを構築するために広く使用されています。 ユニットテストにおけるテスト分離とは、本番コードで他のチームが開発したAPI(クラスメソッド/ファンクションモジュール)を使用することを意味します。実運用コードで、他のチームが開発したAPI(クラスメソッド/関数モジュール)を利用することを意味します。単体テストにおけるテストの分離とは、本番コードで他のチームが開発したAPI(クラスメソッド/関数モジュール)を利用することを意味します。その代わりに、単体テストの実行中に外部APIを呼び出すと、あなた自身が書いたダミーコードに置き換えられることを期待します。この例は、私のプロジェクトのある生産的なクラスから来たものです。 簡単のため、ここでは関連性のないコードを列挙しません。このクラスはZCL_DESTRUCTION_IMG_TOOL_S1です。
主なロジックはクリーンアップ作業です。 すべてのワークリストをループし、依存オブジェクトがあるかどうかをチェックします。 もしあれば、それを削除します。
method RUN.
DATA: lv_social_post_id TYPE string.
fill_worklist( ).
LOOP AT mt_worklist INTO lv_social_post_id.
IF dependent_object_existed( lv_social_post_id ) = abap_false.
delete( lv_social_post_id ).
ENDIF.
ENDLOOP.
endmethod.
The worklist is just hard-coded:
method FILL_WORKLIST.
CLEAR: mt_worklist.
APPEND '' TO mt_worklist.
APPEND '' TO mt_worklist.
APPEND '' TO mt_worklist.
endmethod.
テスト分離がユニットテストで使われる理由は、dependent_object_existed メソッドで他のチームが提供する API を呼び出しているからです。をシミュレートするために次のコードを使います。つまり、this クラスの単体テスト中に、以下のコードが実行されることはありません。
method DEPENDENT_OBJECT_EXISTED.
WRITE: / 'Productive code to check dependent object existence for ID: ' , iv_social_post_id.
endmethod.
Approach1: test subclass instead
DEPENDENT_OBJECT_EXISTEDメソッドのvisibilityをprivateからprotectedに変更します。 アイデアは、thisアプローチでは、次のようになります。このアプローチでは、ZCL_DESTRUCTION_IMG_TOOL_S1を継承するサブクラスを作成します。 DEPENDENT_OBJECT_EXISTEDがprotectedになったので、ローカルのテスト・クラスで再定義するチャンスがあります。ローカル・テスト・クラスで再定義するチャンスがあります。
モックコードは以下のようなシンプルなものです。
METHOD dependent_object_existed.
WRITE: / 'Test mock code to check dependent object existence for ID: ' , iv_social_post_id.
ENDMETHOD.
そしてメソッド開始のコード。
method start.
f_cut = lcl_Destruction_Test=>get_sub_instance( ).
f_cut->run( ).
endmethod.
この "アプローチ "では、実際にユニットテストされるクラスはlcl_destruction_testではありません。destruction_img_tool_s1です。
サブクラスは、dependent_object_existedメソッドだけを再定義しているので、実行がrunメソッドに入ったとき、左のメソッドの実行はまだZCL_DESTRUCTION_IMG_TOOL_S1のコードを使用しています。つまり、ZCL_DESTRUCTION_IMG_TOOL_S1のdependent_object_existed以外の全てのメソッドは、ZCL_DESTRUCTION_IMG_TOOL_S1のコードを使用していることになります。つまり、dependent_object_existed以外のZCL_DESTRUCTION_IMG_TOOL_S1の全てのメソッドが存在します。
そして、dependent_object_existedメソッドを実行すると、現在 "me "はローカルのテスト・サブクラスを指しているので、モック・コードが実行されます。モック・コードが実行されます。
この "アプローチ "の限界は、クラスZCL_DESTRUCTION_IMG_TOOL_S1の作者がfinalであるべきだと主張する場合、そのサブクラスを定義することは不可能だということです。この "方法 "の限界は、クラスZCL_DESTRUCTION_IMG_TOOL_S1の作者がそれをfinalとして定義するべきだと主張する場合、そのサブクラスを定義することは不可能だということです。
Approach2 - この解決策は、可能な限りテストの分離に使用すべきです。+ optional argument
このアイデアは、メソッドdependent_object_existedに書かれたロジックを抽出し、その実装を代わりに新しいインターフェイスZIF_SOC_DEPENDENCY_DETECTORのメソッドdependent_object_existedに置くことです。このような抽象化によって、依存性検出呼び出しとその実装の疎結合が実現されます。達成されます。
プロダクション・クラスZCL_DESTRUCTION_IMG_TOOL_S2のソース・コードで必要な変更があります。
private メソッド dependent_object_existed を削除できるようになりました。
依存性検出の生産的なロジックを実装するローカルクラスを作成します。
run メソッドのオプション引数を作成します。
メソッドの実行では、io_dep_obj_detector に参照が渡されない場合、プロダクションで使用する既定のものが呼び出されます。実際に 1 つの依存オブジェクト検出器が渡された場合は、その検出器を使用します。
また、以前のメソッドdependent_object_existedは削除され、代わりにインターフェイスメソッド呼び出しが使われます。
単体テストクラスは、インターフェイスメソッド dependent_object_existed も実装しています。 単体テストコードでは、メソッド run のオプションパラメータが満たされ、単体テストコード内の インターフェイスメソッドで再定義された依存性検出ロジックが代わりに呼び出されます。単体テストコードでは、メソッド run のオプションパラメータが満たされ、 単体テストコードのインターフェースメソッドで再定義された依存性検出ロジックが 代わりに呼び出されるようになります。
これにより、コンシューマはインタフェースを実装し、オプショ ンを埋めることで、独自の依存性判定ロジックを提供できるようになります。メソッド実行のシグネチャが変更されましたが、これはクリティカルな変更ではありません。 私見では、これは100%のテスト分離ソリューションとは言えません。私見では、100%のテスト分離ソリューションとは言えません。
Approach3 - 動的な検出器の初期化
この "ソリューション "では、インターフェイスの抽出も必要です。 プロダクション・クラス ZCL_DESTRUCTION_IMG_TOOL_S3 で必要な変更TOOL_S3のソース・コードの変更。
アプローチ 2 と同じように、依存性検出の生産ロジックを実装するローカル・クラスを作成します。 technical の新しい静的メンバ属性を追加します。依存クラス名の技術名の新しい静的メンバ属性を追加します。 デフォルト値は、手順 1 で作成したローカル・クラス名です。
メンバ属性 mv_detector_type_name に保持されている名前に従って、検出器のインスタンスを初期化します。 そのデフォルト値はローカルのクラスLCL_PROD_DEP_DETECTORであるため、ランタイムでは生産的な検出ロジックが呼び出されます。
のプライベート属性 mv_detector_type_name も変更できるように、ユニットテスト・クラスをクラス ZCL_DESTRUCTION_IMG_TOOL_S3 のフレンドとして定義します。zcl_destruction_img_tool_s3のプライベート属性mv_detector_type_nameを変更できるようにします。
ユニットテストのコードに、1行(62行目)を追加します。 これで、ユニットテスト・クラスで再定義された検出ロジックが呼び出されるようになります。
アプローチ3は、アプローチ2と比較して、メソッド・シグネチャの変更が不要であるという点で優れています。 クラス・コンシューマは、通常の方法で独自の検出ロジックをクラスに渡す機会がなくなります。しかし、新しいクラス・メンバ属性が導入されるため、次のアプローチ4では不要になる可能性があります。
Approach4 - ディテクタ参照の置換
プロダクション・クラスZCL_DESTRUCTION_IMG_TOOL_S4のソース・コードに必要な変更があります。
アプローチ 3 と同じように、ローカル・クラス lcl_prod_dep_detector に生産的依存性検出ロジックを実装します。 生産的の初期化CONSTRUCTOR で生産的検出器のインスタンスを初期化します。
method CONSTRUCTOR.
CREATE OBJECT mo_dep_obj_detector TYPE lcl_prod_dep_detector .
endmethod.
テスト・クラスでインターフェイス・メソッドを実装します。 単体テスト・クラスを ZCL_DESTRUCTION_IMG_TOOL_S4 のフレンドとして定義します。 単体テスト・コードで、依存性検出器のインスタンスを単体テスト・クラスの参照に置き換えます。単体テストコードでは、依存性検出器のインスタンスを単体テストクラスの参照そのものに置き換えて、独自のロジックが単体テストで呼び出されるようにします。
この "解決策 "では、新しい属性やメソッド・インターフェースの変更は必要ありません。可能な限り、テスト分離のために使用されるべきです。