1

マップでアサーションをテストするのに役立ついくつかの関数を書き始めました。

次のマップがあるとします。

#{a => 0, b => 2}

ビジネスロジックで関数を呼び出した後、マップは次のようになると思います。

#{a => 1, b => 2}

言い換えれば、私は期待しています

  • 更新後に同じ数のキーを持つマップ
  • a0 から 1 に変化する値
  • b不変の値

このテストをパターン マッチングに任せることもできますが、多数のキー (およびおそらく多数のサブマップ) を持つ大きなマップがある場合、問題がどこにあるかは明らかではありません。少なくとも、見つけるのに時間がかかります。問題(更新されると思っていた値が更新されなかった、または余分なキーがあるなど)。

そのため、最初に、モジュールで次のヘルパー関数を思いつきました。

-module(asserts).
-include_lib("eunit/include/eunit.hrl").

maps_assert_map_has_updated_values(BaseMap, Updates, ResultingMap) ->
    BaseMapKeys = lists:sort(maps:keys(BaseMap)),
    ResultingMapKeys = lists:sort(maps:keys(ResultingMap)),
    UpdatesKeys = lists:sort(maps:keys(Updates)),
    BaseMapWithoutUpdates = maps:without(UpdatesKeys, BaseMap),
    BaseMapKeysWithoutUpdates = lists:sort(maps:keys(BaseMapWithoutUpdates)),
    ResultingMapWithoutUpdates = maps:without(UpdatesKeys, ResultingMap),

    [
     ?_assertEqual(BaseMapKeys, ResultingMapKeys),
     lists:foldl(
       fun(Key, Acc) -> [?_assertEqual({Key, maps:get(Key, Updates)}, 
                       {Key, maps:get(Key, ResultingMap)}) | Acc] end,
       [],
       UpdatesKeys
      ),
     lists:foldl(
       fun(Key, Acc) -> [?_assertEqual({Key, true}, 
                       {Key, maps:is_key(Key, ResultingMap)}) | Acc] end,
       [],
       UpdatesKeys
      ),
     lists:foldl(
       fun(Key, Acc) -> [?_assertEqual({Key, maps:get(Key, BaseMapWithoutUpdates)}, 
                       {Key, maps:get(Key, ResultingMapWithoutUpdates)}) | Acc] end,
       [],
       BaseMapKeysWithoutUpdates
      )
    ].

これを、eunit によって実行される別のモジュールから呼び出します。

-module(map_tests).
-include_lib("eunit/include/eunit.hrl").

simple_map_test_() ->
    asserts:maps_assert_map_has_updated_values(
        #{a => 0, b => 2}, 
        #{a => 1}, 
        #{a => 1, b => 3}).

そして、次のエラーメッセージが表示されます。

asserts:30: maps_assert_map_has_updated_values...*failed*    in function asserts:'-maps_assert_map_has_updated_values/3-fun-8-'/3 (test/asserts.erl, line 31)
**error:{assertEqual_failed,[{module,asserts},
                     {line,31},
                     {expression,"{ Key , maps : get ( Key , ResultingMapWithoutUpdates ) }"},
                     {expected,{b,2}},
                     {value,{b,3}}]}

これは、マップ内の問題のあるキーと問題のある値を報告するという点で私が望むものですが、アサーションへの参照ではなく、失敗した実際assertsのテストを見ることに興味があるにもかかわらず、モジュール内にあるエラーを報告しますモジュール。テストジェネレーターはまさにそのために良いと思っていましたが、そのように機能させることはできませんでした.

eunitモジュールの代わりに実際のテスト モジュール (map_tests関数/テストsimple_map_test行 X)をレポートする方法はありassertsますか?

4

1 に答える 1

3

問題は、?_assert...マクロがassertsモジュールにコンパイルされ、そこで EUnit が魔法のようにモジュールと行番号を計算することです (つまり、コンパイル時に)。関数を、インクルードするヘッダー ファイルに配置したマクロに置き換えるmaps_assert_map_has_updated_valuesと、正しいスタック トレースが表示されるはずです。

于 2015-10-16T10:32:05.187 に答える