テスト用にTaskEitherのモックを作る

前のエントリでEither/TaskEitherを使ったエラー処理について書きました。

ある関数を実行した時、「実行が成功したか」と「実行結果」が欲しい場合がよくあります。 C#の時には、タプルを使って (bool:isSuc...

指定したファイルが存在すればその内容を返して、存在しなければErrorを返す関数です。

const readFile = (fileName: string):TE.TaskEither<Error,string> =>
    TE.tryCatch(
            // 正常時に返すもの
            async () => {
                return await fs.readFile(fileName, 'utf-8')
            },
                        
                        // 異常時に返すもの
            (e) => {
                if(e instanceof Error)
                {
                    return e
                }
                else
                {
                    return new Error('failed')
                }
            }
        )

この関数を利用しているユースケース関数をテストしたいと思った時、テスト環境(=指定したファイルが存在するかどうか)がテストの成否に影響してしまうため、モック化したいと思います。
正常系のモックは、無条件でファイルが存在したことにして、その内容を返却する関数を作ればいいことになります。

すると、TaskEitherを返却する関数を作ればいいことになるので、適当に下記のように書いてみました。

const readFileMockOK = (fileName: string):TE.TaskEither<Error,string> =>
{
    return Promise.resolve(E.right("OK, This is Dummy Contents"))
}

これはコンパイルエラーになり動きません。

ここで、Either/Task/TaskEitherの定義に立ち返ってみます。

まずEitherです。

type Either<E, A> = Left<E> | Right<A>

LeftとRightのunion型を持つ型となります

次にTaskです

interface Task<A> {
  (): Promise<A>
}

引数無しで、A型をPromiseで返す「関数」となります。

そしてTaskEitherは、Eitherを上記TaskのA型に入れたものになります。

interface TaskEither<E, A> extends Task<Either<E, A>> {}

なので、TaskEither型を返すモックは、

const readFileMockOK = (fileName: string):TE.TaskEither<Error,string> =>
   () => Promise.resolve(E.right("OK, This is Dummy Contents"))
 
const readFileMockNG = (fileName: string):TE.TaskEither<Error,string> =>
    () => Promise.resolve(E.left(new Error("Dummy Error")))

と書けます。
実はこれはTaskEitherのright/left関数として既に用意されているので、下記のように簡単に書けます。

const readFileMockOK = (fileName: string):TE.TaskEither<Error,string> =>
   TE.right("OK, This is Dummy Contents")
 
const readFileMockNG = (fileName: string):TE.TaskEither<Error,string> =>
    TE.left(new Error("Dummy Error"))
スポンサーリンク

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

スポンサーリンク