##はじめに
この記事は、「ABAP Unitを使ってみよう」シリーズの4回目です。
過去の記事はこちら↓
【ABAP】ABAP Unitを使ってみよう(1) ~簡単なところから
【ABAP】ABAP Unitを使ってみよう(2) ~Test Doubleで依存性を解決する
【ABAP】ABAP Unitを使ってみよう(3) ~CDSビューのテスト
##CDS Test Double Frameworkでセッション変数をコントロールできるのか?
CDSビューで、パラメータやwhere句にセッション変数(ログオンユーザ、言語など)を指定している場合があります。Unitテストでは、実行環境やユーザによって結果が変わってほしくないので、セッション変数をコントロールしたいです。
ヘルプには、CDS Test Double Framework(TDF)でセッション変数のTest Doubleを作れると書いてあったのですが、結局のところやり方がわかりませんでした。
今回の記事では、以下について書きたいと思います。
- できなかったこと
- 代替案
###1. できなかったこと
####テスト対象のビュー
登録ユーザ(CREATED_BY)が、セッション変数のユーザ(実行ユーザ)であるレコードを取得するCDSビューです。
define view ZMOB49_I_PRICE
as select from zprice
{
//zprice
key material,
text,
price,
currency,
created_by
}where created_by = $session.user
####テストクラス
前回と同様の手順でテストクラスを作成しました。
そもそも、セッション変数($session.user)をTest Doubleに置き換える方法がわからなかったので、苦肉の策でsy-unameを書き換えてみました。
" change user
sy-uname = 'TESTUSER'.
SELECT * FROM zmob49_i_price INTO TABLE @act_results.
describe table act_results lines data(lv_cnt).
全体のコード
CLASS ltc_zmob49_i_price IMPLEMENTATION.
METHOD class_setup.
environment = cl_cds_test_environment=>create( i_for_entity = 'ZMOB49_I_PRICE'
test_associations = 'X' ).
ENDMETHOD.
METHOD setup.
environment->clear_doubles( ).
ENDMETHOD.
METHOD class_teardown.
environment->destroy( ).
ENDMETHOD.
METHOD get_data.
prepare_testdata_set( ).
" change user
sy-uname = 'TESTUSER'.
SELECT * FROM zmob49_i_price INTO TABLE @act_results.
describe table act_results lines data(lv_cnt).
cl_abap_unit_assert=>assert_equals(
EXPORTING
act = lv_cnt
exp = 1
msg = 'No record found for TESTUSER'
quit = if_aunit_constants=>quit-test
).
ENDMETHOD.
METHOD prepare_testdata_set.
"Prepare test data for 'zprice'
lt_zprice = VALUE #(
(
mandt = sy-mandt
material = 'M-001'
text = 'TEST'
created_by = 'TESTUSER'
) ).
environment->insert_test_data( i_data = lt_zprice ).
ENDMETHOD.
テストデータ作成時に、登録ユーザを自分のユーザに変えたら成功したので、やはり上記の方法ではセッション変数を書き換えることはできないということです。
lt_zprice = VALUE #(
(
mandt = sy-mandt
material = 'M-001'
text = 'TEST'
created_by = '自分のユーザ'
) ).
###2. 代替案
####①パラメータでユーザを指定する
CDSビューのwhere句でセッション変数を指定するのではなく、パラメータに対象のユーザを渡す方式にします。
define view ZMOB49_I_PRICE
with parameters
@Environment.systemField: #USER
P_user: syst_uname
as select from zprice
{
//zprice
key material,
text,
price,
currency,
created_by
}where created_by = $parameters.P_user
アノテーション@Environment.systemField: #USER
をつけると、パラメータが指定されない場合は実行ユーザが設定されます。
#####テストクラス
CDSビューからレコードを取得するときに、パラメータに任意のユーザを指定します。
SELECT * FROM zmob49_i_price( p_user = 'TESTUSER' ) INTO TABLE @act_results.
describe table act_results lines data(lv_cnt).
####②テストデータを登録するときに、登録者にSY-UNAMEを指定する
こちらは実機で試していませんが、うまくいくはずです。
ただ、感覚的には外部からコントロールできるパラメータで指定する①のほうがいい作りのような気がします。
lt_zprice = VALUE #(
(
mandt = sy-mandt
material = 'M-001'
text = 'TEST'
created_by = sy-uname
) ).
##調べる過程で見つけたもの
以下のパッケージに、Test Doubleを使ったサンプルのテストクラスが入っています。
- SABAP_UNIT_DOUBLE_CDS_DEMO:CDS Test Double Frameworkのデモ
- SABAP_UNIT_DOUBLE_OSQL_DEMO:ABAP SQL Test Double Frameworkのデモ