0
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 1 year has passed since last update.

F#でNUnit+FsUnit+Moqを使って単体テストをする

Last updated at Posted at 2023-04-15

はじめに

F#を使ってユニットテストしたいですよね。
.NETでmockと言えばMoqですよね。
Moqを使ってユニットテストを試してみましょう。

前提

テスト用のプロジェクト作成からやっていきます。
dotnetのコマンドをぽちぽち打ちながらやっていきます。

下準備

ソリューション作成

今回はNUnitMoqというソリューションを作ります。
その下にテスト対象のプロジェクトとテストプロジェクトを作っていきます。

mkdir NUnitMoq
cd NUnitMoq

# ソリューション作成
dotnet new sln

プロジェクト作成

テスト対象のプロジェクトとテストプロジェクトを作ります。

# テスト対象のプロジェクト作成
dotnet new console -lang="F#" -o="Sample"
# テストプロジェクトを作成
dotnet new nunit -lang="F#" -o="SampleTest"

それぞれのプロジェクトをソリューションに紐付けます。

dotnet sln NUnitMoq.sln add Sample
dotnet sln NUnitMoq.sln add SampleTest

テストプロジェクトからテスト対象プロジェクトへの参照を追加します。

dotnet add SampleTest reference Sample

FsUnitとMoqの依存を追加

SampleTest配下でこれをする。

dotnet add package FsUnit --version 5.2.0
dotnet add package Moq --version 4.18.4

テスト対象

TestTarget.fs
module TestTarget

open System
open GetDataPort

let getDataWithUpperLetter (getData: GetData) (dataType: DataType) = 
    getData dataType |> String.map Char.ToUpper
GetDataPort.fs
module GetDataPort

type DataType = TypeA | TypeB
type GetData = DataType -> string
GetData.fs
module GetData

open GetDataPort

let getData (x: DataType) = 
    match x with
        | TypeA -> "hoge"
        | TypeB -> "piyo"

テスト対象になるのはTestTarget.fsgetDataWithUpperLetterです。
GetDataPortGetDataを引数として受け取っています。
今回のテストでは、GetDataをmockしていきます。
※GetDataのイメージが付きやすくなるように、GetData.fsのソースものっけましたが、今回のテストをするだけならGetData.fsは不要です

テストを書いてみる

GetDataWithUpperLetterTest.fs
open System
open NUnit.Framework
open FsUnit
open Moq
open TestTarget
open GetDataPort

[<TestFixture>]
module GetDataWithUpperLetterTest =
    [<Test>]
    let ``Moqを使ってテストするぞ``() =
        // モックの作成
        let getDataMock = new Mock<GetData>()

        // モックのセットアップ
        getDataMock.Setup(fun x -> x DataType.TypeA).Returns "Hello World"

        // モックのオブジェクトを取得
        let getData = getDataMock.Object

        // テスト実行
        getDataWithUpperLetter getData DataType.TypeA |> should equal "HELLO WORLD"

        // モックが期待通り動いたか確認
        getDataMock.VerifyAll()

SampleTest配下でdotnet testを打つとテストが実行されます。
VerifyAll()はセットアップしたモックが正しく呼ばれているかなどを確認できる。

感想

一部C#っぽ記法が出ちゃうのは残念ですが、mockのパッケージを使えるのはありがたい。
色々端折ったところが多いので、ソース見たい方は下記を参照してください。

追記

モックが呼ばれていないことはVerifyNoOtherCallsで確認できそう

open System
open NUnit.Framework
open FsUnit
open Moq
open TestTarget
open GetDataPort

[<TestFixture>]
module GetDataWithUpperLetterTest =
    [<Test>]
    let ``Moqを使ってテストするぞ``() =
        // モックの作成
        let getDataMock = new Mock<GetData>()
        // モックのセットアップ
        getDataMock.Setup(fun x -> x DataType.TypeA).Returns "Hello World"

        // モックのオブジェクトを取得
        let getData = getDataMock.Object

        // 呼ばれない予定のモック
        let notCallMock = new Mock<NotCall>()
        let notCall = notCallMock.Object

        // テスト実行
        getDataWithUpperLetter getData DataType.TypeA notCall |> should equal "HELLO WORLD"

        // モックが期待通り動いたか確認
        getDataMock.VerifyAll()
        // モックが呼ばれていないことの確認
        notCallMock.VerifyNoOtherCalls()

参考

0
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
0
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?