1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【ABAP】ABAP Unitを使ってみよう(4) ~CDS:セッション変数をTest Doubleにしようとして失敗した話

Last updated at Posted at 2019-12-14

##はじめに
この記事は、「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. できなかったこと
  2. 代替案

###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.

結果はNGでした。
image.png

テストデータ作成時に、登録ユーザを自分のユーザに変えたら成功したので、やはり上記の方法ではセッション変数を書き換えることはできないということです。

    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).

結果、テストはOKになりました。
image.png

####②テストデータを登録するときに、登録者に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のデモ
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?