{"componentChunkName":"component---src-modules-datocms-post-page-page-tsx","path":"/posts/38","result":{"data":{"post":{"title":"【テスト駆動開発】スタブ、モック、フェイク、ダミーの違いとは?","author":{"name":"reoring","images":{"r32":{"src":"https://www.datocms-assets.com/29850/1591833154-735890.jpg?auto=format&fm=png&h=32&mask=ellipse&w=32","srcSet":"https://www.datocms-assets.com/29850/1591833154-735890.jpg?auto=format&dpr=1&fm=png&h=32&mask=ellipse&w=32 1x,\nhttps://www.datocms-assets.com/29850/1591833154-735890.jpg?auto=format&dpr=1.5&fm=png&h=32&mask=ellipse&w=32 1.5x,\nhttps://www.datocms-assets.com/29850/1591833154-735890.jpg?auto=format&dpr=2&fm=png&h=32&mask=ellipse&w=32 2x,\nhttps://www.datocms-assets.com/29850/1591833154-735890.jpg?auto=format&dpr=3&fm=png&h=32&mask=ellipse&w=32 3x"},"r48":{"src":"https://www.datocms-assets.com/29850/1591833154-735890.jpg?auto=format&fm=png&h=48&mask=ellipse&w=48","srcSet":"https://www.datocms-assets.com/29850/1591833154-735890.jpg?auto=format&dpr=1&fm=png&h=48&mask=ellipse&w=48 1x,\nhttps://www.datocms-assets.com/29850/1591833154-735890.jpg?auto=format&dpr=1.5&fm=png&h=48&mask=ellipse&w=48 1.5x,\nhttps://www.datocms-assets.com/29850/1591833154-735890.jpg?auto=format&dpr=2&fm=png&h=48&mask=ellipse&w=48 2x,\nhttps://www.datocms-assets.com/29850/1591833154-735890.jpg?auto=format&dpr=3&fm=png&h=48&mask=ellipse&w=48 3x"}},"bio":"株式会社クラフトマンソフトウェア代表 | Schoo講師 | 分報発祥の会社 | YYPHP主催 | マンガでわかるDocker監修 | 実践ドメイン駆動設計レビュア | 自動受け入れテスト ShouldBee http://shouldbee.at/"},"date":"2015年10月12日","tags":["TDD","Scala","stub","mock","fake","dummy"],"category":"ShouldBee","body":"<a href=\"https://c16e-esa-io-public-files.s3-ap-northeast-1.amazonaws.com/uploads/production/attachments/15637/2020/05/28/18740/41ae519d-9dd2-40ca-8283-b06363a9a366.png\" target=\"_blank\" rel=\"noopener noreferrer\"><img width=\"1200\" alt=\"image.png (77.9 kB)\" src=\"https://c16e-esa-io-public-files.s3-ap-northeast-1.amazonaws.com/uploads/production/attachments/15637/2020/05/28/18740/41ae519d-9dd2-40ca-8283-b06363a9a366.png\"></a>\n<p data-sourcepos=\"3:1-3:62\">どうもこんにちは! こんばんは! れおりんです!</p>\n<p data-sourcepos=\"5:1-5:350\">プログラミングをしてテストを記述するときに、モックオブジェクトとか、スタブとかフェイクとか色々な用語があって混乱しますね? 僕は混乱します。開発の打ち合わせなどで開発者間で用語の統一ができておらず、さらに混乱するという場面もありますね。</p>\n<p data-sourcepos=\"7:1-7:72\">今回は、それらの違いを説明してみたいと思います。</p>\n<h1 data-sourcepos=\"9:1-9:11\" id=\"1-0-0\" name=\"1-0-0\">\n<a class=\"anchor\" id=\"スタブ\" name=\"%E3%82%B9%E3%82%BF%E3%83%96\" href=\"#%E3%82%B9%E3%82%BF%E3%83%96\" data-position=\"1-0-0\"><i class=\"fa fa-link\"></i><span class=\"hidden\" data-text=\"スタブ\"> &gt; スタブ</span></a>スタブ</h1>\n<p data-sourcepos=\"11:1-11:72\">スタブは日本語だと、「代用部品」となるようです。</p>\n<p data-sourcepos=\"13:1-13:354\">スタブは、実際の挙動をシミュレートしてテスト実行の支援をするためのものです。スタブとなっているオブジェクトは入力によって出力が変化するようなもの作れますが、とにかく一定の値を返すようなオブジェクトをスタブと呼ぶときが多いように感じます。</p>\n<p data-sourcepos=\"15:1-15:168\">オブジェクトの関連のなかで、スタブは他のオブジェクトには依存しません。単純に値やオブジェクトを返却するだけです。</p>\n<div class=\"code-block\" data-sourcepos=\"17:1-26:3\">\n<div class=\"code-filename\">\n<i class=\"fa fa-file-code-o\"></i>scala</div>\n<div class=\"highlight\"><pre class=\"highlight scala\"><code><span class=\"k\">class</span> <span class=\"nc\">UserDatabaseStub</span> <span class=\"o\">{</span>\n  <span class=\"k\">def</span> <span class=\"nf\">getUserById</span><span class=\"o\">(</span><span class=\"n\">userId</span><span class=\"k\">:</span> <span class=\"kt\">Int</span><span class=\"o\">)</span><span class=\"k\">:</span> <span class=\"kt\">User</span> <span class=\"o\">=</span> <span class=\"o\">{</span>\n    <span class=\"n\">userId</span> <span class=\"k\">match</span> <span class=\"o\">{</span>\n      <span class=\"k\">case</span> <span class=\"mi\">123</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">User</span><span class=\"o\">(</span><span class=\"mi\">123</span><span class=\"o\">,</span> <span class=\"s\">\"Alice\"</span><span class=\"o\">)</span>\n      <span class=\"k\">case</span> <span class=\"mi\">456</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">User</span><span class=\"o\">(</span><span class=\"mi\">456</span><span class=\"o\">,</span> <span class=\"s\">\"Bob\"</span><span class=\"o\">)</span>\n    <span class=\"o\">}</span>\n  <span class=\"o\">}</span>\n<span class=\"o\">}</span>\n</code></pre></div>\n</div>\n<p data-sourcepos=\"28:1-28:314\">jMockやScalaMockといったライブラリを使うと、スタブも作成もライブラリに任せることができます。上の例では自力で実装していますが、ある程度の規模だとスタブの実装も時間がかかりますので、ライブラリを活用していきましょう。</p>\n<p data-sourcepos=\"30:1-30:123\">以下の例は、ScalaMockを使ってユーザオブジェクトを返すUserDatabaseスタブを作成する例です。</p>\n<div class=\"code-block\" data-sourcepos=\"32:1-39:3\">\n<div class=\"code-filename\">\n<i class=\"fa fa-file-code-o\"></i>scala</div>\n<div class=\"highlight\"><pre class=\"highlight scala\"><code><span class=\"k\">val</span> <span class=\"nv\">usersDb</span> <span class=\"k\">=</span> <span class=\"n\">stub</span><span class=\"o\">[</span><span class=\"kt\">UsersDatabase</span><span class=\"o\">]</span>\n\n<span class=\"o\">(</span><span class=\"nv\">usersDb</span><span class=\"o\">.</span><span class=\"py\">getUserById</span> <span class=\"k\">_</span><span class=\"o\">)</span> <span class=\"nf\">when</span><span class=\"o\">(</span><span class=\"mi\">123</span><span class=\"o\">)</span> <span class=\"nf\">returns</span><span class=\"o\">(</span><span class=\"nc\">User</span><span class=\"o\">(</span><span class=\"mi\">123</span><span class=\"o\">,</span> <span class=\"s\">\"Alice\"</span><span class=\"o\">))</span>\n<span class=\"o\">(</span><span class=\"nv\">usersDb</span><span class=\"o\">.</span><span class=\"py\">getUserById</span> <span class=\"k\">_</span><span class=\"o\">)</span> <span class=\"nf\">when</span><span class=\"o\">(</span><span class=\"mi\">456</span><span class=\"o\">)</span> <span class=\"nf\">returns</span><span class=\"o\">(</span><span class=\"nc\">User</span><span class=\"o\">(</span><span class=\"mi\">456</span><span class=\"o\">,</span> <span class=\"s\">\"Bob\"</span><span class=\"o\">))</span>\n\n<span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nv\">usersDb</span><span class=\"o\">.</span><span class=\"py\">getUserById</span><span class=\"o\">(</span><span class=\"mi\">123</span><span class=\"o\">).</span><span class=\"py\">name</span> <span class=\"o\">==</span> <span class=\"s\">\"Alice\"</span><span class=\"o\">)</span>\n</code></pre></div>\n</div>\n<h1 data-sourcepos=\"41:1-41:11\" id=\"2-0-0\" name=\"2-0-0\">\n<a class=\"anchor\" id=\"モック\" name=\"%E3%83%A2%E3%83%83%E3%82%AF\" href=\"#%E3%83%A2%E3%83%83%E3%82%AF\" data-position=\"2-0-0\"><i class=\"fa fa-link\"></i><span class=\"hidden\" data-text=\"モック\"> &gt; モック</span></a>モック</h1>\n<p data-sourcepos=\"43:1-43:369\">モックは日本語だと、「模擬の」という意味ですね。モックはスタブと似ていますが、モックはエクスペクテーションを確認するために使います。エクスペクテーションとは、あるオブジェクトが隣接のオブジェクトとどのような連携をするのかを確かめるためのものです。</p>\n<p data-sourcepos=\"45:1-45:158\">モックは自分で実装する手間を省くために、jMockや、ScalaMockなどのライブラリに任せてしまう場合が多いと思います。</p>\n<p data-sourcepos=\"47:1-47:149\">以下の例は、UserRepositoryが期待通りにApplicationServiceから使われているかを確認するScalaMockを使ったテストです。</p>\n<div class=\"code-block\" data-sourcepos=\"49:1-60:3\">\n<div class=\"code-filename\">\n<i class=\"fa fa-file-code-o\"></i>scala</div>\n<div class=\"highlight\"><pre class=\"highlight scala\"><code><span class=\"k\">def</span> <span class=\"nf\">testAuthentication</span> <span class=\"o\">{</span>\n  <span class=\"k\">val</span> <span class=\"nv\">expectedUser</span> <span class=\"k\">=</span> <span class=\"nc\">User</span><span class=\"o\">(</span><span class=\"mi\">123</span><span class=\"o\">,</span> <span class=\"s\">\"Alice\"</span><span class=\"o\">)</span>\n\n  <span class=\"k\">val</span> <span class=\"nv\">mockedUserRepository</span> <span class=\"k\">=</span> <span class=\"n\">mock</span><span class=\"o\">[</span><span class=\"kt\">UserRepository</span><span class=\"o\">]</span>\n  <span class=\"o\">(</span><span class=\"nv\">UserRepository</span><span class=\"o\">.</span><span class=\"py\">getUserByEmailAddress</span> <span class=\"k\">_</span><span class=\"o\">).</span><span class=\"py\">expects</span><span class=\"o\">(</span><span class=\"s\">\"alice@example.org\"</span><span class=\"o\">).</span><span class=\"py\">returning</span><span class=\"o\">(</span><span class=\"n\">expectedUser</span><span class=\"o\">)</span>\n  <span class=\"o\">(</span><span class=\"nv\">UserRepository</span><span class=\"o\">.</span><span class=\"py\">updateRecentlyAccessedUser</span> <span class=\"k\">_</span><span class=\"o\">).</span><span class=\"py\">expects</span><span class=\"o\">(</span><span class=\"n\">expectedUser</span><span class=\"o\">)</span>\n\n  <span class=\"k\">val</span> <span class=\"nv\">authApplicationService</span> <span class=\"k\">=</span> <span class=\"k\">new</span> <span class=\"nc\">AuthApplicationService</span><span class=\"o\">(</span><span class=\"n\">mockedUserRepository</span><span class=\"o\">)</span>\n  <span class=\"nv\">authApplicationService</span><span class=\"o\">.</span><span class=\"py\">auth</span><span class=\"o\">(</span><span class=\"s\">\"alice@example.org\"</span><span class=\"o\">,</span> <span class=\"s\">\"dummy-password\"</span><span class=\"o\">))</span>\n<span class=\"o\">}</span>\n</code></pre></div>\n</div>\n<h1 data-sourcepos=\"62:1-62:14\" id=\"3-0-0\" name=\"3-0-0\">\n<a class=\"anchor\" id=\"フェイク\" name=\"%E3%83%95%E3%82%A7%E3%82%A4%E3%82%AF\" href=\"#%E3%83%95%E3%82%A7%E3%82%A4%E3%82%AF\" data-position=\"3-0-0\"><i class=\"fa fa-link\"></i><span class=\"hidden\" data-text=\"フェイク\"> &gt; フェイク</span></a>フェイク</h1>\n<p data-sourcepos=\"64:1-64:293\">フェイクは日本語だと「偽物」ですね。よくあるフェイクオブジェクトの使われ方は、プロダクション環境では本物のデータベースだけど、単体テスト環境ではインメモリ(データベースの偽物)というのが多いですね。</p>\n<p data-sourcepos=\"66:1-66:104\">MySQLUserRepositoryが実際のレポジトリで、FakeはInMemoryRepositoryの様に使われます。</p>\n<h1 data-sourcepos=\"68:1-68:11\" id=\"4-0-0\" name=\"4-0-0\">\n<a class=\"anchor\" id=\"ダミー\" name=\"%E3%83%80%E3%83%9F%E3%83%BC\" href=\"#%E3%83%80%E3%83%9F%E3%83%BC\" data-position=\"4-0-0\"><i class=\"fa fa-link\"></i><span class=\"hidden\" data-text=\"ダミー\"> &gt; ダミー</span></a>ダミー</h1>\n<p data-sourcepos=\"70:1-70:285\">ダミーは日本語だと「仮」となります。単純にダミーの値が渡されるだけで、テスト対象にはなりません。例えばダミーのメールアドレスや、パスワードといったリテラルに近い値やオブジェクトに使われます。</p>\n<h1 data-sourcepos=\"72:1-72:8\" id=\"5-0-0\" name=\"5-0-0\">\n<a class=\"anchor\" id=\"参照\" name=\"%E5%8F%82%E7%85%A7\" href=\"#%E5%8F%82%E7%85%A7\" data-position=\"5-0-0\"><i class=\"fa fa-link\"></i><span class=\"hidden\" data-text=\"参照\"> &gt; 参照</span></a>参照</h1>\n<ul data-sourcepos=\"74:1-76:81\">\n<li data-sourcepos=\"74:1-74:36\"><a href=\"http://scalamock.org/\" target=\"_blank\" rel=\"noopener noreferrer\">ScalaMock</a></li>\n<li data-sourcepos=\"75:1-75:32\"><a href=\"http://www.jmock.org/\" target=\"_blank\" rel=\"noopener noreferrer\">jMock</a></li>\n<li data-sourcepos=\"76:1-76:81\"><a href=\"http://www.martinfowler.com/articles/mocksArentStubs.html\" target=\"_blank\" rel=\"noopener noreferrer\">Mocks Aren't Stubs</a></li>\n</ul>\n"}},"pageContext":{"id":"DatoCmsPost-5142973-ja","description":"どうもこんにちは! こんばんは! れおりんです! プログラミングをしてテストを記述するときに、モックオブジェクトとか、スタブとかフェイクとか色々な用語があって混乱しますね? 僕は混乱します。開発の打ち合わせなどで開発者間で用語の統一ができておらず、さらに混乱するという場面もありますね。 今回は、それらの違いを説明してみたいと思います。 スタブ スタブは日本語だと、「代用部品」となるようです。 スタブは、実際の挙動をシミュレートしてテスト実行の支援をするためのものです。スタブとなっているオブジェクトは入力によって出力が変化するようなもの作れますが、とにかく一定の値を返すようなオブジェクトをスタブ","toc":[{"tag":"h1","depth":1,"href":"#%E3%82%B9%E3%82%BF%E3%83%96","text":"スタブ","html":"スタブ"},{"tag":"h1","depth":1,"href":"#%E3%83%A2%E3%83%83%E3%82%AF","text":"モック","html":"モック"},{"tag":"h1","depth":1,"href":"#%E3%83%95%E3%82%A7%E3%82%A4%E3%82%AF","text":"フェイク","html":"フェイク"},{"tag":"h1","depth":1,"href":"#%E3%83%80%E3%83%9F%E3%83%BC","text":"ダミー","html":"ダミー"},{"tag":"h1","depth":1,"href":"#%E5%8F%82%E7%85%A7","text":"参照","html":"参照"}],"ogpImageUrl":"https://www.datocms-assets.com/29850/1593190022-pastedimage20200627146.png?fm=png&mark64=aHR0cHM6Ly93d3cuZGF0b2Ntcy1hc3NldHMuY29tLzI5ODUwLzE1OTMxNTQ2MzYtdHJhbnNwYXJlbnQtcGl4ZWwucG5nP3c9NDAwJmg9NjQmZml0PWNyb3AmYmxlbmQ2ND1hSFIwY0hNNkx5OTNkM2N1WkdGMGIyTnRjeTFoYzNObGRITXVZMjl0THpJNU9EVXdMekUxT1RFNE16TXhOVFF0TnpNMU9Ea3dMbXB3Wno5dFlYTnJQV1ZzYkdsd2MyVW1abTA5Y0c1bkpuYzlNalUySm1nOU1qVTImYmxlbmQtaD02NCZibGVuZC14PTAmYmxlbmQteT0wJmJsZW5kLW1vZGU9bm9ybWFsJm1hcms2ND1hSFIwY0hNNkx5OWhjM05sZEhNdWFXMW5hWGd1Ym1WMEwzNTBaWGgwUDNSNGRDMWhiR2xuYmoxdGFXUmtiR1VsTWtOc1pXWjBKblI0ZEMxbWIyNTBQWE5oYm5NdGMyVnlhV1lsTWtOaWIyeGtKblI0ZEMxamIyeHZjajB5TWpFNE1UWW1kSGgwTmpROVkyMVdkbU50YkhWYWR5WjBlSFF0YzJsNlpUMHpNQ1pvUFRZMCZtYXJrLXg9NjQmbWFyay1hbGlnbj1taWRkbGUlMkNsZWZ0&mark-align=bottom%2Cleft&mark-x=100&mark-y=496&blend64=aHR0cHM6Ly93d3cuZGF0b2Ntcy1hc3NldHMuY29tLzI5ODUwLzE1OTMxNTQ2MzYtdHJhbnNwYXJlbnQtcGl4ZWwucG5nP3c9MTIwMCZoPTYzMCZmaXQ9Y3JvcCZtYXJrNjQ9YUhSMGNITTZMeTkzZDNjdVpHRjBiMk50Y3kxaGMzTmxkSE11WTI5dEx6STVPRFV3THpFMU9UTXhOVEE1TkRBdFkzSmhablJ6YldGdUxUQXhMbkJ1WncmbWFyay1hbGlnbj10b3AlMkNjZW50ZXImbWFyay13PTI1MCZtYXJrLXk9ODAmYmxlbmQ2ND1hSFIwY0hNNkx5OWhjM05sZEhNdWFXMW5hWGd1Ym1WMEwzNTBaWGgwUDNSNGRDMWhiR2xuYmoxdGFXUmtiR1VsTWtOalpXNTBaWEltZEhoMExXWnZiblE5YzJGdWN5MXpaWEpwWmlVeVEySnZiR1FtZEhoMExYQmhaRDB4TURBbWRIaDBMV052Ykc5eVBUSXlNVGd4TmlaMGVIUTJORDAwTkVOUk5EUlBSelEwU3pVME5FOUpObUZsUnpWWmRWWTJXbUZNTlRWdE5qUTBRMUkwTkVzMU5EUkxYelEwVDFjME5FTkNORFJQYVRRMFQwUTBORXQyTkRSRFFqUTBUMVkwTkV0dU5EUkxhelEwUzNZME5FTkNORFJQUVRRMFQyWTBORTg0TkRSSGRUWlpSMVkwTkVkRk5EUkhielEwUjNaUWR5WjBlSFF0YzJsNlpUMDFOU1ozUFRFeU1EQW1hRDAyTXpBJmJsZW5kLW1vZGU9bm9ybWFs&blend-mode=normal"}}}