bugfix> testing > 投稿

Elmアプリケーションでデバウンス機能をテストしようとしていますが、その方法がわかりません。

デバウンスはファジー検索用のテキストフィールドに適用され、httpリクエストが多くなりすぎないようにします。この例ではモデル化されていますhttps://ellie-app.com/jNmstCdv3va1 そして、同じロジックに従います。

type alias Model =
    { search : Maybe String 
    , searchResult : List User
    , debouncingCounter : Int
    }
init : Model
init = 
    { search = Nothing
    , searchResult = [] 
    , debouncingCounter = 0
    }
debounceTime : Time
debounceTime = 350 * Time.millisecond
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
    case msg of 
        (...)
        SearchInput search ->
            let 
                newCounter = model.debouncingCounter + 1
            in
            case search o
                "" -> ({model | search = Nothing, searchResult = []}, Cmd.none)
            _ -> 
                ({ model | search = Just search, debouncingCounter = newCounter }
                , Process.sleep debounceTime |> Task.perform (always (Timeout newCounter)))
        Timeout int ->
            if int==model.debouncingCounter then
                (update SendSearch {model | debouncingCounter = 0 })
            else 
                (update NoOperation model)
        SendSearch ->
            case model.search of 
                Nothing -> 
                    (model, Cmd.none)
                Just string -> 
                    let 
                        cmd = Http.send ReSendSearch <| postApiAdminUserSearchByQuery string
                    in
                    (model, cmd)
        ReSendSearch result ->
            case result of 
                Err _ -> 
                    (model, Cmd.none)
                Ok usersList -> 
                    ({model | searchResult = usersList}, Cmd.none )

電話した後、それを確実にしたい

update (searchInput "string") init

HttpリクエストはdebounceTimeの後にのみ送信されます。

searchInputメッセージで更新関数が呼び出された直後に、モデルを簡単にテストできます。たとえば、ここでは、モデルの「debouncingCounter」フィールドの初期値が1に設定されることを確認します。

startDebounce : Test
startDebounce =
test "debouncingCounter is set to 1 after search input is updated" <|
    \_ ->
        Users.init
            |> Users.update (Users.SearchInput "abc") 
            |> Tuple.first
            |> .debouncingCounter
            |> Expect.equal 1

ただし、更新関数によって返されたcmd値を直接適用できないため、モデルに対する遅延Cmd Msgの効果をどのようにテストできるかわかりません。

Process.sleep debounceTime |> Task.perform (always (Timeout newCounter))

デバウンスを実装するさまざまな方法は、すべてコマンドメッセージに依存しているため、問題を解決できないようです。

回答 1 件
  • テストしたい内容に応じて、異なるアプローチに従うことができます。

    テストしたい場合

    SearchInput のコード  適切なコマンドを返す: あなたは elm-testable の使用を検討するかもしれません 。

    Process.sleep を実行するelmランタイム  正しくコマンド: これは、統合/エンドツーエンドのテストシナリオに分類されます。そのため、エンドツーエンド/ JSツールのいずれかを使用して、コンパイルされた完全なアプリをテストする必要があります。

    Timeout x を処理するコード  メッセージが適切に: そのための別のテストケースを書くだけです。

あなたの答え