0Pricing
Scala for Backend Engineering & Functional Programming · レッスン

モックとフィクスチャ

テストをセットアップします。

「モックとフィクスチャ」はCoddyKit上の無料Scala for Backend Engineering & Functional Programmingレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはScala for Backend Engineering & Functional Programming学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Scala for Backend Engineering & Functional Programmingコースには全4レッスンが含まれています。

テストのセットアップと後処理

多くのテストでは、共有フィクスチャが必要です。これは、テスト前に準備し、テスト後に片付けるデータやリソースです。ScalaTestには、セットアップコードを重複させずに管理する方法が複数あります。

単純なフィクスチャ:メソッドだけを使う

最も単純なフィクスチャは、新しい状態を構築するヘルパーメソッドです。各テストがこのメソッドを呼び出すため、テストの分離が保証されます。

import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers

class StackSpec extends AnyFlatSpec with Matchers {
  def emptyStack(): scala.collection.mutable.Stack[Int] =
    scala.collection.mutable.Stack.empty[Int]

  "a stack" should "start empty" in {
    emptyStack().size shouldBe 0
  }
}

BeforeAndAfter

BeforeAndAfterをミックスインすると、before { }ブロックとafter { }ブロックで各テストの前後にコードを実行できます。

import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import org.scalatest.BeforeAndAfter

class DbSpec extends AnyFlatSpec with Matchers with BeforeAndAfter {
  var counter = 0
  before { counter = 10 }
  after  { counter = 0 }

  "counter" should "be initialized" in {
    counter shouldBe 10
  }
}

BeforeAndAfterAll

データベース接続や組み込みサーバーなど、スイート内のすべてのテストで共有する高コストなリソースには、beforeAllとafterAllを備えたBeforeAndAfterAllを使います。

import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.BeforeAndAfterAll

class ServerSpec extends AnyFlatSpec with BeforeAndAfterAll {
  override def beforeAll(): Unit = println("start server")
  override def afterAll(): Unit  = println("stop server")

  "server" should "respond" in {
    assert(true)
  }
}

ローン・フィクスチャパターン

ローンパターンでは、新しく構築したリソースをテスト本体に渡し、テストが失敗した場合でもfinallyで確実に後処理します。

import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers

class FileSpec extends AnyFlatSpec with Matchers {
  def withBuffer(test: StringBuilder => Any): Unit = {
    val buf = new StringBuilder("init")
    try test(buf)
    finally buf.clear()
  }

  "a buffer" should "start with init" in withBuffer { buf =>
    buf.toString shouldBe "init"
  }
}

なぜモックを使うのか

モックは、ユニットテストを高速かつ決定的に保つための、実際の依存関係(データベースやHTTPクライアントなど)の代用品です。モックが返す値を制御し、どのように呼び出されたかを検証できます。

Mockitoの追加

ScalaTestはscalatestplusを介してMockitoと統合できます。依存関係を追加し、MockitoSugarをミックスインします。

libraryDependencies += "org.scalatestplus" %% "mockito-5-10" % "3.2.18.0" % Test

メソッドのスタブ化

モックを作成し、when(...).thenReturn(...)でその振る舞いを設定します。その後、テストでモックに依存するコードを実行します。

import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import org.scalatestplus.mockito.MockitoSugar
import org.mockito.Mockito.when

trait Repo { def find(id: Int): String }

class RepoSpec extends AnyFlatSpec with Matchers with MockitoSugar {
  "a repo" should "return stubbed value" in {
    val repo = mock[Repo]
    when(repo.find(1)).thenReturn("Alice")
    repo.find(1) shouldBe "Alice"
  }
}

インタラクションの検証

戻り値だけでなく、メソッドが期待した回数だけ呼び出されたことをverifyで検証できます。

import org.scalatest.flatspec.AnyFlatSpec
import org.scalatestplus.mockito.MockitoSugar
import org.mockito.Mockito.{verify, times}

trait Logger { def log(msg: String): Unit }

class LogSpec extends AnyFlatSpec with MockitoSugar {
  "a service" should "log once" in {
    val logger = mock[Logger]
    logger.log("hi")
    verify(logger, times(1)).log("hi")
  }
}

モック、スタブ、フェイクの違い

用語:

  • Stub:あらかじめ決めた値を返します。
  • Mock:インタラクションも検証できます。
  • Fake:軽量で実際に動作する実装です(インメモリリポジトリなど)。

単純な場合はフェイクまたは実際のオブジェクトを優先し、本当に外部にある依存関係だけをモックしてください。

テストを分離する

フィクスチャとモックの目的は、各テストを既知の独立した状態で実行することです。各テストの前に共有された可変状態をリセットし、テスト間で可変フィクスチャを共有しないようにして、不安定で実行順序に依存する失敗を防ぎます。

クイックチェック

フィクスチャとモックについての知識を確認しましょう。

まとめ

フィクスチャとモックについて学びました。

  • フィクスチャ:ヘルパーメソッド、BeforeAndAfter、BeforeAndAfterAll、ローンパターン。
  • モック(MockitoSugar経由):when().thenReturn()でスタブ化し、verifyで呼び出しを確認します。
  • 単純なケースではフェイクを優先し、外部依存関係にはモックを使います。
  • すべてのテストを分離し、実行順序に依存しないようにします。

よくある質問

「モックとフィクスチャ」レッスンは無料ですか?

はい。「モックとフィクスチャ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Scala for Backend Engineering & Functional Programmingコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Scala for Backend Engineering & Functional Programmingコースには全4レッスンが含まれています。

「モックとフィクスチャ」で何を学びますか?

テストをセットアップします。 ブラウザで直接実行するハンズオンコードでScala for Backend Engineering & Functional Programmingを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Scala for Backend Engineering & Functional Programmingを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのScala for Backend Engineering & Functional Programmingは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「モックとフィクスチャ」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このScala for Backend Engineering & Functional Programmingレッスンでコードを書いて実行できますか?

はい。すべてのScala for Backend Engineering & Functional Programmingレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. ScalaTest のスタイル
  2. Matchers
  3. プロパティベーステスト
  4. モックとフィクスチャ
← Scala for Backend Engineering & Functional Programmingに戻る