SlideShare une entreprise Scribd logo
1  sur  37
XunitとMoqの使い方
2017/3/11 1Copyright (c) 2017 Eiwa System Management, Inc.
株式会社永和システムマネジメント
コンサルティングセンター
センター長 天野勝
http://www.esm.co.jp/service/consulting/
 OS
 Windows10
 Visual Studio
 Visual Studio 2015 Community
2Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11
動作確認環境
 以下のサイトを参考にさせていただきました。
 ありがとうございます。
 xUnitを使用したC#のテストでSetUpやTearDown、Theory –
Symfoware
http://symfoware.blog68.fc2.com/blog-entry-1062.html
 【ハウツー】Moqを活用して.NETでモックを使ったテストを行う | マイナ
ビニュース
http://news.mynavi.jp/articles/2009/06/15/moq/menu.html
 【C#】【Mock】Moq(モッキュ) ~文法編~
http://blogs.yahoo.co.jp/dk521123/21216313.html
 Quickstart · moq/moq4 Wiki
https://github.com/Moq/moq4/wiki/Quickstart
 Moq.dllを使ってみた - 割と普通なブログ
http://normalian.hatenablog.com/entry/20090907/1252344523
 Moq(モックライブラリー)を使ってみる。 | 84zume Works
https://84zume.wordpress.com/2012/02/11/moqing/
3Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11
謝辞
Xunit
2017/3/11 4Copyright (c) 2017 Eiwa System Management, Inc.
インストール
2017/3/11 5Copyright (c) 2017 Eiwa System Management, Inc.
 NuGetを起動する
 「xunit」をインストールする
 「xunit.runner.visualstudio」をインストールする
 Visual Studioから起動するためのテストランナー
6Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11
NuGetからインストールする
テストケースクラスの作成
2017/3/11 7Copyright (c) 2017 Eiwa System Management, Inc.
 using Xunit
 publicなクラス
 publicな引数無しのメソッドに[Fact]を付ける
 戻り値はあってもよい
 テストエクスプローラーから実行する
8Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11
テストケース[Fact]
 テストケースの名称を変えたいとき
 [Fact(DisplayName = "名前")]
 テストケースをスキップしたいとき
 [Fact(Skip = "スキップする理由")]
9Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11
テストケース[Fact]
 [InlineData()]で、テストメソッドに値を渡せる
 InlineData以外の方法もあり
 テストメソッドの引数と、同型、同数でなくてはならない
10Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11
テストケース[Theory]
 using Xunit.Abstractions
 コンストラクターで出力先のストリーム(ITestOutputHelper)を
受け取り、WriteLine()を呼び出す
 テストエクスプローラーの「出力」をクリックして確認する
11Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11
メッセージを出力をする場合
 SetUpはクラスのコンストラクタに書く
 TearDownはIDisposableを実装し、Disposeメソッドに書く
12Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11
SetUpとTearDown
表明メソッド
2017/3/11 13Copyright (c) 2017 Eiwa System Management, Inc.
14Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11
表明メソッド
[Fact(DisplayName = "標準的な表明メソッド")]
public void TestAssert()
{
// 2つの値が等しいか、否か
Assert.Equal(10, 0 + 10);
Assert.Equal("10", "" + 10);
Assert.NotEqual(0.3 + 0.6, 0.9);
// 2つのオブジェクトが同一か、否か
string s = "10";
Assert.Same(s, "10");
Assert.NotSame(s, "" + 10);
// nullかどうか
int? i = null;
Assert.Null(i);
i = 0;
Assert.NotNull(i);
// tureかfalseか
Assert.True((0xFF00 ^ 0x00FF) == 0xFFFF);
Assert.False((1 ^ 0) == -1);
}
15Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11
表明メソッド
[Fact(DisplayName = "文字列の表明メソッド")]
public void TestStringAssert()
{
// 文字列を含むか、否か
Assert.Contains("BC", "ABCDEFG");
Assert.DoesNotContain("bc", "ABCDEFG");
// 文字列が空かどうか
Assert.Empty("");
Assert.NotEmpty("*");
// 指定した文字列で始まっているか
Assert.StartsWith("AB", "ABCDEF");
// 指定した文字列で終わっているか
Assert.EndsWith("YZ", "UVWXYZ");
// 正規表現を満たしているか、否か
Assert.Matches(@"No¥.[0-9]{3}$", "No.789");
Assert.DoesNotMatch(@"No¥.[0-9]{3}$", "No.7890");
}
16Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11
表明メソッド
[Fact]
public void TestException()
{
// 例外が発生することを期待
Assert.ThrowsAny<ArgumentException>(() =>
{
throw new ArgumentNullException();
});
}
 本系のサイトを参考
 https://github.com/xunit/samples.xunit
17Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11
表明メソッドのサンプル
応用例
2017/3/11 18Copyright (c) 2017 Eiwa System Management, Inc.
19Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11
CSVファイルをテストデータに使用する
a,b,result
1,2,3
4,5,9
10,11,21
TestData.csv
20Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11
CSVファイルをテストデータに使用する
using Xunit;
using Xunit.Abstractions;
namespace FirstTest
{
public class CsvSample
{
private ITestOutputHelper _output;
public CsvSample(ITestOutputHelper output)
{
_output = output;
}
[Theory]
[CsvData("../../TestData.csv")]
public void TestUseCsvFile(int v1, int v2, int result)
{
_output.WriteLine(string.Format($"{v1},{v2},{result}"));
Assert.Equal(result, v1 + v2);
}
}
}
CsvSample.cs
21Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11
CSVファイルをテストデータに使用する
using System;
using System.Collections.Generic;
using System.Linq;
using Xunit.Sdk;
using System.Reflection;
using System.IO;
namespace FirstTest
{
// 独自の属性の定義
// 属性の対象はメソッド
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class CsvDataAttribute : DataAttribute // クラス名から「Attribute」を除いた文字列が属性名になる
{
private string _filename;
// 1つの値をとるコンストラクタ
public CsvDataAttribute(string filename)
{
_filename = filename;
}
CsvDataAttribute.cs (1/3)
22Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11
CSVファイルをテストデータに使用する
public override IEnumerable<object[]> GetData(MethodInfo testMethod)
{
ParameterInfo[] pars = testMethod.GetParameters();
return DataSource(pars.Select((par) => par.ParameterType).ToArray());
}
private IEnumerable<object[]> DataSource(Type[] parameterTypes)
{
using (var reader = new StreamReader(_filename))
{
string line = reader.ReadLine(); // 1行目はヘッダーなので読み飛ばす
for (line = reader.ReadLine(); line != null; line = reader.ReadLine())
{
var rowData = line.Split(','); // 単純にカンマで区切って配列にする
yield return ConvertParameters(rowData, parameterTypes);
}
}
}
CsvDataAttribute.cs (2/3)
23Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11
CSVファイルをテストデータに使用する
private static object[] ConvertParameters(object[] values, Type[] parameterTypes)
{
object[] result = new object[values.Length];
for (int i = 0; i < values.Length; i++)
{
result[i] = ConvertParameter(values[i], i >= parameterTypes.Length ? null : parameterTypes[i]);
}
return result;
}
private static object ConvertParameter(object parameter, Type parameterType)
{
if ((parameter is double || parameter is float) &&
(parameterType == typeof(int) || parameterType == typeof(int?)))
{
int intValue;
string floatValueAsString = parameter.ToString();
if (Int32.TryParse(floatValueAsString, out intValue))
{
return intValue;
}
}
return parameter;
}
}
}
CsvDataAttribute.cs (3/3)
Moq
2017/3/11 24Copyright (c) 2017 Eiwa System Management, Inc.
インストール
2017/3/11 25Copyright (c) 2017 Eiwa System Management, Inc.
 NuGetを起動する
 「Moq」をインストールする
26Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11
NuGetからインストールする
使用方法
2017/3/11 27Copyright (c) 2017 Eiwa System Management, Inc.
28Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11
サンプル テスト対象クラス
public interface ICalc
{
int Sub(int v1, int v2);
}
public class Calc : ICalc
{
// Stub化されるメソッドは、オーバーライド可能(virtual)にしておく
public virtual int Add(int v1, int v2)
{
return 100;
}
public int Sub(int v1, int v2)
{
throw new NotImplementedException();
}
}
Calc.cs
29Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11
サンプル Setup、Returns
[Fact(DisplayName = "引数に値を指定してスタブ化")]
public void TestStubExactMatch()
{
var calcMock = new Mock<Calc>(); // Calcクラスをラップする
// CalcクラスのAddメソッドが、引数「1」「2」で呼ばれたら「3」を返す
calcMock.Setup(m => m.Add(1, 2)).Returns(3);
Calc c = calcMock.Object; // Calc形のインスタンスを取り出す
Assert.Equal(3, c.Add(1, 2)); // 指定した呼び出しなので、「3」を返す
Assert.Equal(0, c.Add(2, 1)); // 設定した引数の組み合わせ以外は「0」を返す
}
MoqStubSample.cs
30Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11
サンプル It.IsAny
[Fact(DisplayName = "1つの引数に値を指定してスタブ化")]
public void TestStubAnyMatch()
{
var calcMock = new Mock<ICalc>(); // IClassインタフェースをラップ
// 第1引数はなんでもよい、第2引数が2ならばSubメソッドは3を返す
calcMock.Setup(m => m.Sub(It.IsAny<int>(), 2)).Returns(3);
ICalc c = calcMock.Object;
Assert.Equal(3, c.Sub(1, 2)); // 第2引数が2ならば3を返す
Assert.Equal(3, c.Sub(2, 2)); // 第2引数が2ならば3を返す
Assert.Equal(0, c.Sub(2, 1)); // 第2引数が2以外ならば0を返す
}
MoqStubSample.cs
31Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11
サンプル When
[Fact(DisplayName = "Whenを使って、Setupの条件を指定する")]
public void TestWhen()
{
int count = 0;
var mock = new Mock<Calc>();
// countが偶数の時は、引数の値が何であろうと、Addメソッドは0を返す
mock.When(() => (count % 2 == 0)).Setup(
(m) => m.Add(It.IsAny<int>(), It.IsAny<int>()))
.Returns(0);
// countが奇数の時は、引数の値が何であろうと、Addメソッドは1を返す
mock.When(() => (count % 2 != 0)).Setup(
(m) => m.Add(It.IsAny<int>(), It.IsAny<int>()))
.Returns(1);
count = 10;
Assert.Equal(0, mock.Object.Add(0, 0)); // countが10(偶数)なので、0を返す
count = 11;
Assert.Equal(1, mock.Object.Add(0, 0)); // countが11(奇数)なので、1を返す
}
MoqStubSample.cs
32Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11
サンプル WhenとInlineDataの組合せ
[Theory(DisplayName = "MoqのWhenと、XunitのInlineDataの組合せ")]
[InlineData(10, 0)]
[InlineData(11, 1)]
[InlineData(-10, 0)]
[InlineData(-11, 1)]
public void TestWhenAndInlineData(int count, int expected)
{
var mock = new Mock<Calc>();
// countが偶数の時は、引数の値が何であろうと、Addメソッドは0を返す
mock.When(() => (count % 2 == 0)).Setup(
(m) => m.Add(It.IsAny<int>(), It.IsAny<int>()))
.Returns(0);
// countが奇数の時は、引数の値が何であろうと、Addメソッドは1を返す
mock.When(() => (count % 2 != 0)).Setup(
(m) => m.Add(It.IsAny<int>(), It.IsAny<int>()))
.Returns(1);
Assert.Equal(expected, mock.Object.Add(0, 0));
}
MoqStubSample.cs
33Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11
サンプル テスト対象クラス
public class JsonWriter : IDisposable
{
private TextWriter _writer;
public JsonWriter(TextWriter writer)
{
_writer = writer;
}
public void Dispose() => _writer.Close();
public void Write(string key, string value)
{
string s = string.Format(@"{{""{0}"":""{1}""}}", key, value);
_writer.Write(s); // 引数の型はstring
}
public void Write(string key, int value)
{
_writer.Write(@"{{""{0}"":{1}}}", key, value); // 引数の型はstring, string, int
}
public void Write(string key, double value)
{
_writer.Write(@"{{""{0}"":{1}}}", key, value); // 引数の型はstring, string, double
}
}
JsonWriter.cs
34Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11
サンプル Callback
[Fact(DisplayName = "Callbackの使い方。整形してファイルに出力しているかを確認する")]
public void TestCallback()
{
var mock = new Mock<TextWriter>();
mock.Setup((m) => m.Write(It.IsAny<string>()))
.Callback<string>(s =>
{
Assert.Equal(@"{""name"":""テス太郎""}", s); // (1)
});
mock.Setup((m) => m.Write(It.IsAny<string>(), It.IsAny<object>(), It.IsAny<int>()))
.Callback<string, object, object>((format, name, value) =>
{
Assert.Equal("age", name); // (2)
Assert.Equal(13, value);
});
mock.Setup((m) => m.Write(It.IsAny<string>(), It.IsAny<object>(), It.IsAny<double>()))
.Callback<string, object, object>((format, name, value) =>
{
Assert.Equal("height", name); // (3)
Assert.Equal(175.5, value);
});
TextWriter tw = mock.Object;
var writer = new JsonWriter(tw);
writer.Write("name", "テス太郎"); // (1)が呼ばれる
writer.Write("age", 13); // (2)が呼ばれる
writer.Write("height", 175.5); // (3)が呼ばれる
MoqMockSample.cs
35Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11
サンプル Throws
[Fact(DisplayName = "Throwsの使い方")]
public void TestThrows()
{
var mock = new Mock<TextWriter>();
mock.Setup(
(m) => m.Write(It.IsAny<string>())) // Writeメソッドが呼ばれると
.Throws<FileNotFoundException>(); // IOExceptionの派生クラスの
// FileNotFoundExeptionを発生させる
var writer = new JsonWriter(mock.Object);
Assert.ThrowsAny<IOException>(
() =>
{
writer.Write("name", "テス太郎");
});
}
MoqMockSample.cs
36Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11
サンプル Verify
[Fact(DisplayName = "Verifyの使い方")]
public void TestVerify()
{
var mock = new Mock<TextWriter>();
var writer = new JsonWriter(mock.Object);
writer.Write("name", "テス太郎"); // 内部でstring, string, stringが呼ばれる。1回目
// Write(string, string, int)は1回も呼ばれていない
mock.Verify((m) => m.Write(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>()), Times.Never());
// Write(string, string, int)は最大でも1回しか呼ばれていない(実際は0回)
mock.Verify((m) => m.Write(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>()), Times.AtMostOnce());
// Write(string, string, int)は最大でも3回しか呼ばれていない(実際は0回)
mock.Verify((m) => m.Write(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>()), Times.AtMost(3));
// Write(string)は一回は呼ばれている
mock.Verify((m) => m.Write(It.IsAny<string>()), Times.AtLeastOnce());
// Write(string)は1回だけ呼ばれている
mock.Verify((m) => m.Write(It.IsAny<string>()), Times.Once());
writer.Write("name", "テス太郎"); // 内部でstring, string, stringが呼ばれる。2回目
// Write(string)は2回だけ呼ばれている
mock.Verify((m) => m.Write(It.IsAny<string>()), Times.Exactly(2));
}
MoqMockSample.cs
37Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11
サンプル VerifyAll
[Fact(DisplayName = "VerifyAllの使い方")]
public void TestVerifyAll()
{
var mock = new Mock<TextWriter>();
mock.Setup(
(m) => m.Write(It.IsAny<string>()));
var writer = new JsonWriter(mock.Object);
// SetUpした箇所がすべて呼ばれていないときにMockException発生
Assert.ThrowsAny<MockException>(
() =>
{
mock.VerifyAll();
});
}
MoqMockSample.cs

Contenu connexe

Tendances

マイクロサービスにおけるテスト自動化 with Karate
マイクロサービスにおけるテスト自動化 with Karateマイクロサービスにおけるテスト自動化 with Karate
マイクロサービスにおけるテスト自動化 with KarateTakanori Suzuki
 
Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24
Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24
Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24Shin Ohno
 
シリコンバレーの「何が」凄いのか
シリコンバレーの「何が」凄いのかシリコンバレーの「何が」凄いのか
シリコンバレーの「何が」凄いのかAtsushi Nakada
 
やはりお前らのMVCは間違っている
やはりお前らのMVCは間違っているやはりお前らのMVCは間違っている
やはりお前らのMVCは間違っているKoichi Tanaka
 
ドメイン駆動設計に15年取り組んでわかったこと
ドメイン駆動設計に15年取り組んでわかったことドメイン駆動設計に15年取り組んでわかったこと
ドメイン駆動設計に15年取り組んでわかったこと増田 亨
 
ドメイン駆動設計サンプルコードの徹底解説
ドメイン駆動設計サンプルコードの徹底解説ドメイン駆動設計サンプルコードの徹底解説
ドメイン駆動設計サンプルコードの徹底解説増田 亨
 
怖くないSpring Bootのオートコンフィグレーション
怖くないSpring Bootのオートコンフィグレーション怖くないSpring Bootのオートコンフィグレーション
怖くないSpring Bootのオートコンフィグレーション土岐 孝平
 
オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?Moriharu Ohzu
 
組織にテストを書く文化を根付かせる戦略と戦術
組織にテストを書く文化を根付かせる戦略と戦術組織にテストを書く文化を根付かせる戦略と戦術
組織にテストを書く文化を根付かせる戦略と戦術Takuto Wada
 
受託開発でテストファーストしたらXXXを早期発見できてハイアジリティになったはなし
受託開発でテストファーストしたらXXXを早期発見できてハイアジリティになったはなし受託開発でテストファーストしたらXXXを早期発見できてハイアジリティになったはなし
受託開発でテストファーストしたらXXXを早期発見できてハイアジリティになったはなしterahide
 
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考えるGoのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考えるpospome
 
serviceクラスをやめようサブクラスを使おう
serviceクラスをやめようサブクラスを使おうserviceクラスをやめようサブクラスを使おう
serviceクラスをやめようサブクラスを使おうよしだ あつし
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Kohei Tokunaga
 
AKS と ACI を組み合わせて使ってみた
AKS と ACI を組み合わせて使ってみたAKS と ACI を組み合わせて使ってみた
AKS と ACI を組み合わせて使ってみたHideaki Aoyagi
 
オブジェクト指向プログラミング入門 -- Java object-oriented programming primer
オブジェクト指向プログラミング入門 -- Java object-oriented programming primerオブジェクト指向プログラミング入門 -- Java object-oriented programming primer
オブジェクト指向プログラミング入門 -- Java object-oriented programming primer増田 亨
 
人生がときめくAPIテスト自動化 with Karate
人生がときめくAPIテスト自動化 with Karate人生がときめくAPIテスト自動化 with Karate
人生がときめくAPIテスト自動化 with KarateTakanori Suzuki
 
こわくない Git
こわくない Gitこわくない Git
こわくない GitKota Saito
 
認証の標準的な方法は分かった。では認可はどう管理するんだい? #cmdevio
認証の標準的な方法は分かった。では認可はどう管理するんだい? #cmdevio認証の標準的な方法は分かった。では認可はどう管理するんだい? #cmdevio
認証の標準的な方法は分かった。では認可はどう管理するんだい? #cmdevio都元ダイスケ Miyamoto
 
乗っ取れコンテナ!!開発者から見たコンテナセキュリティの考え方(CloudNative Days Tokyo 2021 発表資料)
乗っ取れコンテナ!!開発者から見たコンテナセキュリティの考え方(CloudNative Days Tokyo 2021 発表資料)乗っ取れコンテナ!!開発者から見たコンテナセキュリティの考え方(CloudNative Days Tokyo 2021 発表資料)
乗っ取れコンテナ!!開発者から見たコンテナセキュリティの考え方(CloudNative Days Tokyo 2021 発表資料)NTT DATA Technology & Innovation
 

Tendances (20)

マイクロサービスにおけるテスト自動化 with Karate
マイクロサービスにおけるテスト自動化 with Karateマイクロサービスにおけるテスト自動化 with Karate
マイクロサービスにおけるテスト自動化 with Karate
 
Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24
Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24
Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24
 
シリコンバレーの「何が」凄いのか
シリコンバレーの「何が」凄いのかシリコンバレーの「何が」凄いのか
シリコンバレーの「何が」凄いのか
 
やはりお前らのMVCは間違っている
やはりお前らのMVCは間違っているやはりお前らのMVCは間違っている
やはりお前らのMVCは間違っている
 
ドメイン駆動設計に15年取り組んでわかったこと
ドメイン駆動設計に15年取り組んでわかったことドメイン駆動設計に15年取り組んでわかったこと
ドメイン駆動設計に15年取り組んでわかったこと
 
ドメイン駆動設計サンプルコードの徹底解説
ドメイン駆動設計サンプルコードの徹底解説ドメイン駆動設計サンプルコードの徹底解説
ドメイン駆動設計サンプルコードの徹底解説
 
怖くないSpring Bootのオートコンフィグレーション
怖くないSpring Bootのオートコンフィグレーション怖くないSpring Bootのオートコンフィグレーション
怖くないSpring Bootのオートコンフィグレーション
 
オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?
 
組織にテストを書く文化を根付かせる戦略と戦術
組織にテストを書く文化を根付かせる戦略と戦術組織にテストを書く文化を根付かせる戦略と戦術
組織にテストを書く文化を根付かせる戦略と戦術
 
受託開発でテストファーストしたらXXXを早期発見できてハイアジリティになったはなし
受託開発でテストファーストしたらXXXを早期発見できてハイアジリティになったはなし受託開発でテストファーストしたらXXXを早期発見できてハイアジリティになったはなし
受託開発でテストファーストしたらXXXを早期発見できてハイアジリティになったはなし
 
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考えるGoのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
 
serviceクラスをやめようサブクラスを使おう
serviceクラスをやめようサブクラスを使おうserviceクラスをやめようサブクラスを使おう
serviceクラスをやめようサブクラスを使おう
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行
 
AKS と ACI を組み合わせて使ってみた
AKS と ACI を組み合わせて使ってみたAKS と ACI を組み合わせて使ってみた
AKS と ACI を組み合わせて使ってみた
 
オブジェクト指向プログラミング入門 -- Java object-oriented programming primer
オブジェクト指向プログラミング入門 -- Java object-oriented programming primerオブジェクト指向プログラミング入門 -- Java object-oriented programming primer
オブジェクト指向プログラミング入門 -- Java object-oriented programming primer
 
SpringBootTest入門
SpringBootTest入門SpringBootTest入門
SpringBootTest入門
 
人生がときめくAPIテスト自動化 with Karate
人生がときめくAPIテスト自動化 with Karate人生がときめくAPIテスト自動化 with Karate
人生がときめくAPIテスト自動化 with Karate
 
こわくない Git
こわくない Gitこわくない Git
こわくない Git
 
認証の標準的な方法は分かった。では認可はどう管理するんだい? #cmdevio
認証の標準的な方法は分かった。では認可はどう管理するんだい? #cmdevio認証の標準的な方法は分かった。では認可はどう管理するんだい? #cmdevio
認証の標準的な方法は分かった。では認可はどう管理するんだい? #cmdevio
 
乗っ取れコンテナ!!開発者から見たコンテナセキュリティの考え方(CloudNative Days Tokyo 2021 発表資料)
乗っ取れコンテナ!!開発者から見たコンテナセキュリティの考え方(CloudNative Days Tokyo 2021 発表資料)乗っ取れコンテナ!!開発者から見たコンテナセキュリティの考え方(CloudNative Days Tokyo 2021 発表資料)
乗っ取れコンテナ!!開発者から見たコンテナセキュリティの考え方(CloudNative Days Tokyo 2021 発表資料)
 

Similaire à XunitとMoq 公開用

「Entity Framework Coreを使ってみる」 公開用
「Entity Framework Coreを使ってみる」 公開用「Entity Framework Coreを使ってみる」 公開用
「Entity Framework Coreを使ってみる」 公開用ESM SEC
 
Sencha ug3 siesta_share
Sencha ug3 siesta_shareSencha ug3 siesta_share
Sencha ug3 siesta_share久司 中村
 
Azure Machine Learning Services 概要 - 2019年2月版
Azure Machine Learning Services 概要 - 2019年2月版Azure Machine Learning Services 概要 - 2019年2月版
Azure Machine Learning Services 概要 - 2019年2月版Daiyu Hatakeyama
 
Test Manager + Team Foundation Server /Visual Studio Team Services 手順書(共有パラメー...
Test Manager + Team Foundation Server /Visual Studio Team Services 手順書(共有パラメー...Test Manager + Team Foundation Server /Visual Studio Team Services 手順書(共有パラメー...
Test Manager + Team Foundation Server /Visual Studio Team Services 手順書(共有パラメー...Masaki Takeda
 
Linux 対応だけじゃない!! sql server 2017 こんな機能が追加されています。
Linux 対応だけじゃない!! sql server 2017 こんな機能が追加されています。Linux 対応だけじゃない!! sql server 2017 こんな機能が追加されています。
Linux 対応だけじゃない!! sql server 2017 こんな機能が追加されています。Masayuki Ozawa
 
Optuna on Kubeflow Pipeline 分散ハイパラチューニング
Optuna on Kubeflow Pipeline 分散ハイパラチューニングOptuna on Kubeflow Pipeline 分散ハイパラチューニング
Optuna on Kubeflow Pipeline 分散ハイパラチューニングTakashi Suzuki
 
Azure IoT Edge で Custom Vision
Azure IoT Edge で Custom VisionAzure IoT Edge で Custom Vision
Azure IoT Edge で Custom VisionYoshitaka Seo
 
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~normalian
 
エンタープライズ分野での実践AngularJS
エンタープライズ分野での実践AngularJSエンタープライズ分野での実践AngularJS
エンタープライズ分野での実践AngularJSAyumi Goto
 
Team Foundation Server / Visual Studio Team Services によるプロジェクト管理・リポジトリ管理・継続的イ...
Team Foundation Server / Visual Studio Team Services によるプロジェクト管理・リポジトリ管理・継続的イ...Team Foundation Server / Visual Studio Team Services によるプロジェクト管理・リポジトリ管理・継続的イ...
Team Foundation Server / Visual Studio Team Services によるプロジェクト管理・リポジトリ管理・継続的イ...Masaki Takeda
 
機械学習 / Deep Learning 大全 (5) Tool編
機械学習 / Deep Learning 大全 (5) Tool編機械学習 / Deep Learning 大全 (5) Tool編
機械学習 / Deep Learning 大全 (5) Tool編Daiyu Hatakeyama
 
Team Foundation Server / Visual Studio Team Services 手順書
Team Foundation Server /Visual Studio Team Services 手順書Team Foundation Server /Visual Studio Team Services 手順書
Team Foundation Server / Visual Studio Team Services 手順書Masaki Takeda
 
Entity Framework 6.1.3 + Windows フォーム サンプル アプリケーション構築 手順書
Entity Framework 6.1.3 + Windows フォームサンプル アプリケーション構築手順書Entity Framework 6.1.3 + Windows フォームサンプル アプリケーション構築手順書
Entity Framework 6.1.3 + Windows フォーム サンプル アプリケーション構築 手順書Masaki Takeda
 
復習も兼ねて!C#6.0-7.0
復習も兼ねて!C#6.0-7.0復習も兼ねて!C#6.0-7.0
復習も兼ねて!C#6.0-7.0Yuta Matsumura
 
Windows ストア lob アプリ開発のためのガイダンスとフレームワークのご紹介 rev
Windows ストア lob アプリ開発のためのガイダンスとフレームワークのご紹介 revWindows ストア lob アプリ開発のためのガイダンスとフレームワークのご紹介 rev
Windows ストア lob アプリ開発のためのガイダンスとフレームワークのご紹介 revShotaro Suzuki
 
コーディング不要! Entity Framework 6.1.3 + ASP.NET MVC 5 サンプル アプリケーション構築 手順書
コーディング不要!Entity Framework 6.1.3 + ASP.NET MVC 5 サンプル アプリケーション構築 手順書コーディング不要!Entity Framework 6.1.3 + ASP.NET MVC 5 サンプル アプリケーション構築 手順書
コーディング不要! Entity Framework 6.1.3 + ASP.NET MVC 5 サンプル アプリケーション構築 手順書Masaki Takeda
 
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例Yoshifumi Kawai
 
Let's build a simple app with .net 6 asp.net core web api, react, and elasti...
Let's build a simple app with  .net 6 asp.net core web api, react, and elasti...Let's build a simple app with  .net 6 asp.net core web api, react, and elasti...
Let's build a simple app with .net 6 asp.net core web api, react, and elasti...Shotaro Suzuki
 
C# Database操作3 データの更新-
C# Database操作3  データの更新-C# Database操作3  データの更新-
C# Database操作3 データの更新-Hiroki Takahashi
 

Similaire à XunitとMoq 公開用 (20)

「Entity Framework Coreを使ってみる」 公開用
「Entity Framework Coreを使ってみる」 公開用「Entity Framework Coreを使ってみる」 公開用
「Entity Framework Coreを使ってみる」 公開用
 
Sencha ug3 siesta_share
Sencha ug3 siesta_shareSencha ug3 siesta_share
Sencha ug3 siesta_share
 
Azure Machine Learning Services 概要 - 2019年2月版
Azure Machine Learning Services 概要 - 2019年2月版Azure Machine Learning Services 概要 - 2019年2月版
Azure Machine Learning Services 概要 - 2019年2月版
 
Test Manager + Team Foundation Server /Visual Studio Team Services 手順書(共有パラメー...
Test Manager + Team Foundation Server /Visual Studio Team Services 手順書(共有パラメー...Test Manager + Team Foundation Server /Visual Studio Team Services 手順書(共有パラメー...
Test Manager + Team Foundation Server /Visual Studio Team Services 手順書(共有パラメー...
 
Linux 対応だけじゃない!! sql server 2017 こんな機能が追加されています。
Linux 対応だけじゃない!! sql server 2017 こんな機能が追加されています。Linux 対応だけじゃない!! sql server 2017 こんな機能が追加されています。
Linux 対応だけじゃない!! sql server 2017 こんな機能が追加されています。
 
Optuna on Kubeflow Pipeline 分散ハイパラチューニング
Optuna on Kubeflow Pipeline 分散ハイパラチューニングOptuna on Kubeflow Pipeline 分散ハイパラチューニング
Optuna on Kubeflow Pipeline 分散ハイパラチューニング
 
Vue入門
Vue入門Vue入門
Vue入門
 
Azure IoT Edge で Custom Vision
Azure IoT Edge で Custom VisionAzure IoT Edge で Custom Vision
Azure IoT Edge で Custom Vision
 
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
 
エンタープライズ分野での実践AngularJS
エンタープライズ分野での実践AngularJSエンタープライズ分野での実践AngularJS
エンタープライズ分野での実践AngularJS
 
Team Foundation Server / Visual Studio Team Services によるプロジェクト管理・リポジトリ管理・継続的イ...
Team Foundation Server / Visual Studio Team Services によるプロジェクト管理・リポジトリ管理・継続的イ...Team Foundation Server / Visual Studio Team Services によるプロジェクト管理・リポジトリ管理・継続的イ...
Team Foundation Server / Visual Studio Team Services によるプロジェクト管理・リポジトリ管理・継続的イ...
 
機械学習 / Deep Learning 大全 (5) Tool編
機械学習 / Deep Learning 大全 (5) Tool編機械学習 / Deep Learning 大全 (5) Tool編
機械学習 / Deep Learning 大全 (5) Tool編
 
Team Foundation Server / Visual Studio Team Services 手順書
Team Foundation Server /Visual Studio Team Services 手順書Team Foundation Server /Visual Studio Team Services 手順書
Team Foundation Server / Visual Studio Team Services 手順書
 
Entity Framework 6.1.3 + Windows フォーム サンプル アプリケーション構築 手順書
Entity Framework 6.1.3 + Windows フォームサンプル アプリケーション構築手順書Entity Framework 6.1.3 + Windows フォームサンプル アプリケーション構築手順書
Entity Framework 6.1.3 + Windows フォーム サンプル アプリケーション構築 手順書
 
復習も兼ねて!C#6.0-7.0
復習も兼ねて!C#6.0-7.0復習も兼ねて!C#6.0-7.0
復習も兼ねて!C#6.0-7.0
 
Windows ストア lob アプリ開発のためのガイダンスとフレームワークのご紹介 rev
Windows ストア lob アプリ開発のためのガイダンスとフレームワークのご紹介 revWindows ストア lob アプリ開発のためのガイダンスとフレームワークのご紹介 rev
Windows ストア lob アプリ開発のためのガイダンスとフレームワークのご紹介 rev
 
コーディング不要! Entity Framework 6.1.3 + ASP.NET MVC 5 サンプル アプリケーション構築 手順書
コーディング不要!Entity Framework 6.1.3 + ASP.NET MVC 5 サンプル アプリケーション構築 手順書コーディング不要!Entity Framework 6.1.3 + ASP.NET MVC 5 サンプル アプリケーション構築 手順書
コーディング不要! Entity Framework 6.1.3 + ASP.NET MVC 5 サンプル アプリケーション構築 手順書
 
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例
 
Let's build a simple app with .net 6 asp.net core web api, react, and elasti...
Let's build a simple app with  .net 6 asp.net core web api, react, and elasti...Let's build a simple app with  .net 6 asp.net core web api, react, and elasti...
Let's build a simple app with .net 6 asp.net core web api, react, and elasti...
 
C# Database操作3 データの更新-
C# Database操作3  データの更新-C# Database操作3  データの更新-
C# Database操作3 データの更新-
 

Plus de ESM SEC

「ふりかえり」は、Retrospectiveか、Reflectionか
「ふりかえり」は、Retrospectiveか、Reflectionか「ふりかえり」は、Retrospectiveか、Reflectionか
「ふりかえり」は、Retrospectiveか、ReflectionかESM SEC
 
日本におけるアジャイル開発の認知度の変遷を情報処理技術者試験の問題から考察してみた_公開用
日本におけるアジャイル開発の認知度の変遷を情報処理技術者試験の問題から考察してみた_公開用日本におけるアジャイル開発の認知度の変遷を情報処理技術者試験の問題から考察してみた_公開用
日本におけるアジャイル開発の認知度の変遷を情報処理技術者試験の問題から考察してみた_公開用ESM SEC
 
製品の質と、仕事の質を向上させるふりかえりの活用
製品の質と、仕事の質を向上させるふりかえりの活用製品の質と、仕事の質を向上させるふりかえりの活用
製品の質と、仕事の質を向上させるふりかえりの活用ESM SEC
 
ふりかえり支援ツールを用いたリモートふりかえり会のファシリテーション方法の提案
ふりかえり支援ツールを用いたリモートふりかえり会のファシリテーション方法の提案ふりかえり支援ツールを用いたリモートふりかえり会のファシリテーション方法の提案
ふりかえり支援ツールを用いたリモートふりかえり会のファシリテーション方法の提案ESM SEC
 
ふりかえり会は懺悔の場でも責任追及の場でもありません、過去の学びを活かして幸福な未来を作る行動を生み出す場です
ふりかえり会は懺悔の場でも責任追及の場でもありません、過去の学びを活かして幸福な未来を作る行動を生み出す場ですふりかえり会は懺悔の場でも責任追及の場でもありません、過去の学びを活かして幸福な未来を作る行動を生み出す場です
ふりかえり会は懺悔の場でも責任追及の場でもありません、過去の学びを活かして幸福な未来を作る行動を生み出す場ですESM SEC
 
KPTとKPTA
KPTとKPTAKPTとKPTA
KPTとKPTAESM SEC
 
けぷ人とけぷ太
けぷ人とけぷ太けぷ人とけぷ太
けぷ人とけぷ太ESM SEC
 
「システムメタファ」再考 公開用
「システムメタファ」再考 公開用「システムメタファ」再考 公開用
「システムメタファ」再考 公開用ESM SEC
 
アジャイル開発の事例と動向 公開用
アジャイル開発の事例と動向 公開用アジャイル開発の事例と動向 公開用
アジャイル開発の事例と動向 公開用ESM SEC
 
「失敗事例から学ぶアジャイル開発」研修の紹介
「失敗事例から学ぶアジャイル開発」研修の紹介「失敗事例から学ぶアジャイル開発」研修の紹介
「失敗事例から学ぶアジャイル開発」研修の紹介ESM SEC
 
KPTAふりかえり体験研修のご紹介
KPTAふりかえり体験研修のご紹介KPTAふりかえり体験研修のご紹介
KPTAふりかえり体験研修のご紹介ESM SEC
 
ESMのアジャイル開発
ESMのアジャイル開発ESMのアジャイル開発
ESMのアジャイル開発ESM SEC
 
ゼロから始めるプロダクト開発
ゼロから始めるプロダクト開発ゼロから始めるプロダクト開発
ゼロから始めるプロダクト開発ESM SEC
 
アジャイル開発をよりアジャイルに
アジャイル開発をよりアジャイルにアジャイル開発をよりアジャイルに
アジャイル開発をよりアジャイルにESM SEC
 
ふりかえりで学んだこと ベスト10
ふりかえりで学んだこと ベスト10ふりかえりで学んだこと ベスト10
ふりかえりで学んだこと ベスト10ESM SEC
 
「アジャイルコーチの7つ道具」の使い方
「アジャイルコーチの7つ道具」の使い方「アジャイルコーチの7つ道具」の使い方
「アジャイルコーチの7つ道具」の使い方ESM SEC
 
俺たちのKPTA
俺たちのKPTA俺たちのKPTA
俺たちのKPTAESM SEC
 
ワークショップ 明日からはじめるアジャイル
ワークショップ 明日からはじめるアジャイルワークショップ 明日からはじめるアジャイル
ワークショップ 明日からはじめるアジャイルESM SEC
 
アジャイル開発の基礎知識 抜粋版
アジャイル開発の基礎知識 抜粋版アジャイル開発の基礎知識 抜粋版
アジャイル開発の基礎知識 抜粋版ESM SEC
 
Pull Request & TDD 入門
Pull Request & TDD 入門Pull Request & TDD 入門
Pull Request & TDD 入門ESM SEC
 

Plus de ESM SEC (20)

「ふりかえり」は、Retrospectiveか、Reflectionか
「ふりかえり」は、Retrospectiveか、Reflectionか「ふりかえり」は、Retrospectiveか、Reflectionか
「ふりかえり」は、Retrospectiveか、Reflectionか
 
日本におけるアジャイル開発の認知度の変遷を情報処理技術者試験の問題から考察してみた_公開用
日本におけるアジャイル開発の認知度の変遷を情報処理技術者試験の問題から考察してみた_公開用日本におけるアジャイル開発の認知度の変遷を情報処理技術者試験の問題から考察してみた_公開用
日本におけるアジャイル開発の認知度の変遷を情報処理技術者試験の問題から考察してみた_公開用
 
製品の質と、仕事の質を向上させるふりかえりの活用
製品の質と、仕事の質を向上させるふりかえりの活用製品の質と、仕事の質を向上させるふりかえりの活用
製品の質と、仕事の質を向上させるふりかえりの活用
 
ふりかえり支援ツールを用いたリモートふりかえり会のファシリテーション方法の提案
ふりかえり支援ツールを用いたリモートふりかえり会のファシリテーション方法の提案ふりかえり支援ツールを用いたリモートふりかえり会のファシリテーション方法の提案
ふりかえり支援ツールを用いたリモートふりかえり会のファシリテーション方法の提案
 
ふりかえり会は懺悔の場でも責任追及の場でもありません、過去の学びを活かして幸福な未来を作る行動を生み出す場です
ふりかえり会は懺悔の場でも責任追及の場でもありません、過去の学びを活かして幸福な未来を作る行動を生み出す場ですふりかえり会は懺悔の場でも責任追及の場でもありません、過去の学びを活かして幸福な未来を作る行動を生み出す場です
ふりかえり会は懺悔の場でも責任追及の場でもありません、過去の学びを活かして幸福な未来を作る行動を生み出す場です
 
KPTとKPTA
KPTとKPTAKPTとKPTA
KPTとKPTA
 
けぷ人とけぷ太
けぷ人とけぷ太けぷ人とけぷ太
けぷ人とけぷ太
 
「システムメタファ」再考 公開用
「システムメタファ」再考 公開用「システムメタファ」再考 公開用
「システムメタファ」再考 公開用
 
アジャイル開発の事例と動向 公開用
アジャイル開発の事例と動向 公開用アジャイル開発の事例と動向 公開用
アジャイル開発の事例と動向 公開用
 
「失敗事例から学ぶアジャイル開発」研修の紹介
「失敗事例から学ぶアジャイル開発」研修の紹介「失敗事例から学ぶアジャイル開発」研修の紹介
「失敗事例から学ぶアジャイル開発」研修の紹介
 
KPTAふりかえり体験研修のご紹介
KPTAふりかえり体験研修のご紹介KPTAふりかえり体験研修のご紹介
KPTAふりかえり体験研修のご紹介
 
ESMのアジャイル開発
ESMのアジャイル開発ESMのアジャイル開発
ESMのアジャイル開発
 
ゼロから始めるプロダクト開発
ゼロから始めるプロダクト開発ゼロから始めるプロダクト開発
ゼロから始めるプロダクト開発
 
アジャイル開発をよりアジャイルに
アジャイル開発をよりアジャイルにアジャイル開発をよりアジャイルに
アジャイル開発をよりアジャイルに
 
ふりかえりで学んだこと ベスト10
ふりかえりで学んだこと ベスト10ふりかえりで学んだこと ベスト10
ふりかえりで学んだこと ベスト10
 
「アジャイルコーチの7つ道具」の使い方
「アジャイルコーチの7つ道具」の使い方「アジャイルコーチの7つ道具」の使い方
「アジャイルコーチの7つ道具」の使い方
 
俺たちのKPTA
俺たちのKPTA俺たちのKPTA
俺たちのKPTA
 
ワークショップ 明日からはじめるアジャイル
ワークショップ 明日からはじめるアジャイルワークショップ 明日からはじめるアジャイル
ワークショップ 明日からはじめるアジャイル
 
アジャイル開発の基礎知識 抜粋版
アジャイル開発の基礎知識 抜粋版アジャイル開発の基礎知識 抜粋版
アジャイル開発の基礎知識 抜粋版
 
Pull Request & TDD 入門
Pull Request & TDD 入門Pull Request & TDD 入門
Pull Request & TDD 入門
 

XunitとMoq 公開用

  • 1. XunitとMoqの使い方 2017/3/11 1Copyright (c) 2017 Eiwa System Management, Inc. 株式会社永和システムマネジメント コンサルティングセンター センター長 天野勝 http://www.esm.co.jp/service/consulting/
  • 2.  OS  Windows10  Visual Studio  Visual Studio 2015 Community 2Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11 動作確認環境
  • 3.  以下のサイトを参考にさせていただきました。  ありがとうございます。  xUnitを使用したC#のテストでSetUpやTearDown、Theory – Symfoware http://symfoware.blog68.fc2.com/blog-entry-1062.html  【ハウツー】Moqを活用して.NETでモックを使ったテストを行う | マイナ ビニュース http://news.mynavi.jp/articles/2009/06/15/moq/menu.html  【C#】【Mock】Moq(モッキュ) ~文法編~ http://blogs.yahoo.co.jp/dk521123/21216313.html  Quickstart · moq/moq4 Wiki https://github.com/Moq/moq4/wiki/Quickstart  Moq.dllを使ってみた - 割と普通なブログ http://normalian.hatenablog.com/entry/20090907/1252344523  Moq(モックライブラリー)を使ってみる。 | 84zume Works https://84zume.wordpress.com/2012/02/11/moqing/ 3Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11 謝辞
  • 4. Xunit 2017/3/11 4Copyright (c) 2017 Eiwa System Management, Inc.
  • 5. インストール 2017/3/11 5Copyright (c) 2017 Eiwa System Management, Inc.
  • 6.  NuGetを起動する  「xunit」をインストールする  「xunit.runner.visualstudio」をインストールする  Visual Studioから起動するためのテストランナー 6Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11 NuGetからインストールする
  • 8.  using Xunit  publicなクラス  publicな引数無しのメソッドに[Fact]を付ける  戻り値はあってもよい  テストエクスプローラーから実行する 8Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11 テストケース[Fact]
  • 9.  テストケースの名称を変えたいとき  [Fact(DisplayName = "名前")]  テストケースをスキップしたいとき  [Fact(Skip = "スキップする理由")] 9Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11 テストケース[Fact]
  • 10.  [InlineData()]で、テストメソッドに値を渡せる  InlineData以外の方法もあり  テストメソッドの引数と、同型、同数でなくてはならない 10Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11 テストケース[Theory]
  • 11.  using Xunit.Abstractions  コンストラクターで出力先のストリーム(ITestOutputHelper)を 受け取り、WriteLine()を呼び出す  テストエクスプローラーの「出力」をクリックして確認する 11Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11 メッセージを出力をする場合
  • 13. 表明メソッド 2017/3/11 13Copyright (c) 2017 Eiwa System Management, Inc.
  • 14. 14Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11 表明メソッド [Fact(DisplayName = "標準的な表明メソッド")] public void TestAssert() { // 2つの値が等しいか、否か Assert.Equal(10, 0 + 10); Assert.Equal("10", "" + 10); Assert.NotEqual(0.3 + 0.6, 0.9); // 2つのオブジェクトが同一か、否か string s = "10"; Assert.Same(s, "10"); Assert.NotSame(s, "" + 10); // nullかどうか int? i = null; Assert.Null(i); i = 0; Assert.NotNull(i); // tureかfalseか Assert.True((0xFF00 ^ 0x00FF) == 0xFFFF); Assert.False((1 ^ 0) == -1); }
  • 15. 15Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11 表明メソッド [Fact(DisplayName = "文字列の表明メソッド")] public void TestStringAssert() { // 文字列を含むか、否か Assert.Contains("BC", "ABCDEFG"); Assert.DoesNotContain("bc", "ABCDEFG"); // 文字列が空かどうか Assert.Empty(""); Assert.NotEmpty("*"); // 指定した文字列で始まっているか Assert.StartsWith("AB", "ABCDEF"); // 指定した文字列で終わっているか Assert.EndsWith("YZ", "UVWXYZ"); // 正規表現を満たしているか、否か Assert.Matches(@"No¥.[0-9]{3}$", "No.789"); Assert.DoesNotMatch(@"No¥.[0-9]{3}$", "No.7890"); }
  • 16. 16Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11 表明メソッド [Fact] public void TestException() { // 例外が発生することを期待 Assert.ThrowsAny<ArgumentException>(() => { throw new ArgumentNullException(); }); }
  • 17.  本系のサイトを参考  https://github.com/xunit/samples.xunit 17Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11 表明メソッドのサンプル
  • 18. 応用例 2017/3/11 18Copyright (c) 2017 Eiwa System Management, Inc.
  • 19. 19Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11 CSVファイルをテストデータに使用する a,b,result 1,2,3 4,5,9 10,11,21 TestData.csv
  • 20. 20Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11 CSVファイルをテストデータに使用する using Xunit; using Xunit.Abstractions; namespace FirstTest { public class CsvSample { private ITestOutputHelper _output; public CsvSample(ITestOutputHelper output) { _output = output; } [Theory] [CsvData("../../TestData.csv")] public void TestUseCsvFile(int v1, int v2, int result) { _output.WriteLine(string.Format($"{v1},{v2},{result}")); Assert.Equal(result, v1 + v2); } } } CsvSample.cs
  • 21. 21Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11 CSVファイルをテストデータに使用する using System; using System.Collections.Generic; using System.Linq; using Xunit.Sdk; using System.Reflection; using System.IO; namespace FirstTest { // 独自の属性の定義 // 属性の対象はメソッド [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] public class CsvDataAttribute : DataAttribute // クラス名から「Attribute」を除いた文字列が属性名になる { private string _filename; // 1つの値をとるコンストラクタ public CsvDataAttribute(string filename) { _filename = filename; } CsvDataAttribute.cs (1/3)
  • 22. 22Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11 CSVファイルをテストデータに使用する public override IEnumerable<object[]> GetData(MethodInfo testMethod) { ParameterInfo[] pars = testMethod.GetParameters(); return DataSource(pars.Select((par) => par.ParameterType).ToArray()); } private IEnumerable<object[]> DataSource(Type[] parameterTypes) { using (var reader = new StreamReader(_filename)) { string line = reader.ReadLine(); // 1行目はヘッダーなので読み飛ばす for (line = reader.ReadLine(); line != null; line = reader.ReadLine()) { var rowData = line.Split(','); // 単純にカンマで区切って配列にする yield return ConvertParameters(rowData, parameterTypes); } } } CsvDataAttribute.cs (2/3)
  • 23. 23Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11 CSVファイルをテストデータに使用する private static object[] ConvertParameters(object[] values, Type[] parameterTypes) { object[] result = new object[values.Length]; for (int i = 0; i < values.Length; i++) { result[i] = ConvertParameter(values[i], i >= parameterTypes.Length ? null : parameterTypes[i]); } return result; } private static object ConvertParameter(object parameter, Type parameterType) { if ((parameter is double || parameter is float) && (parameterType == typeof(int) || parameterType == typeof(int?))) { int intValue; string floatValueAsString = parameter.ToString(); if (Int32.TryParse(floatValueAsString, out intValue)) { return intValue; } } return parameter; } } } CsvDataAttribute.cs (3/3)
  • 24. Moq 2017/3/11 24Copyright (c) 2017 Eiwa System Management, Inc.
  • 25. インストール 2017/3/11 25Copyright (c) 2017 Eiwa System Management, Inc.
  • 26.  NuGetを起動する  「Moq」をインストールする 26Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11 NuGetからインストールする
  • 27. 使用方法 2017/3/11 27Copyright (c) 2017 Eiwa System Management, Inc.
  • 28. 28Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11 サンプル テスト対象クラス public interface ICalc { int Sub(int v1, int v2); } public class Calc : ICalc { // Stub化されるメソッドは、オーバーライド可能(virtual)にしておく public virtual int Add(int v1, int v2) { return 100; } public int Sub(int v1, int v2) { throw new NotImplementedException(); } } Calc.cs
  • 29. 29Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11 サンプル Setup、Returns [Fact(DisplayName = "引数に値を指定してスタブ化")] public void TestStubExactMatch() { var calcMock = new Mock<Calc>(); // Calcクラスをラップする // CalcクラスのAddメソッドが、引数「1」「2」で呼ばれたら「3」を返す calcMock.Setup(m => m.Add(1, 2)).Returns(3); Calc c = calcMock.Object; // Calc形のインスタンスを取り出す Assert.Equal(3, c.Add(1, 2)); // 指定した呼び出しなので、「3」を返す Assert.Equal(0, c.Add(2, 1)); // 設定した引数の組み合わせ以外は「0」を返す } MoqStubSample.cs
  • 30. 30Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11 サンプル It.IsAny [Fact(DisplayName = "1つの引数に値を指定してスタブ化")] public void TestStubAnyMatch() { var calcMock = new Mock<ICalc>(); // IClassインタフェースをラップ // 第1引数はなんでもよい、第2引数が2ならばSubメソッドは3を返す calcMock.Setup(m => m.Sub(It.IsAny<int>(), 2)).Returns(3); ICalc c = calcMock.Object; Assert.Equal(3, c.Sub(1, 2)); // 第2引数が2ならば3を返す Assert.Equal(3, c.Sub(2, 2)); // 第2引数が2ならば3を返す Assert.Equal(0, c.Sub(2, 1)); // 第2引数が2以外ならば0を返す } MoqStubSample.cs
  • 31. 31Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11 サンプル When [Fact(DisplayName = "Whenを使って、Setupの条件を指定する")] public void TestWhen() { int count = 0; var mock = new Mock<Calc>(); // countが偶数の時は、引数の値が何であろうと、Addメソッドは0を返す mock.When(() => (count % 2 == 0)).Setup( (m) => m.Add(It.IsAny<int>(), It.IsAny<int>())) .Returns(0); // countが奇数の時は、引数の値が何であろうと、Addメソッドは1を返す mock.When(() => (count % 2 != 0)).Setup( (m) => m.Add(It.IsAny<int>(), It.IsAny<int>())) .Returns(1); count = 10; Assert.Equal(0, mock.Object.Add(0, 0)); // countが10(偶数)なので、0を返す count = 11; Assert.Equal(1, mock.Object.Add(0, 0)); // countが11(奇数)なので、1を返す } MoqStubSample.cs
  • 32. 32Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11 サンプル WhenとInlineDataの組合せ [Theory(DisplayName = "MoqのWhenと、XunitのInlineDataの組合せ")] [InlineData(10, 0)] [InlineData(11, 1)] [InlineData(-10, 0)] [InlineData(-11, 1)] public void TestWhenAndInlineData(int count, int expected) { var mock = new Mock<Calc>(); // countが偶数の時は、引数の値が何であろうと、Addメソッドは0を返す mock.When(() => (count % 2 == 0)).Setup( (m) => m.Add(It.IsAny<int>(), It.IsAny<int>())) .Returns(0); // countが奇数の時は、引数の値が何であろうと、Addメソッドは1を返す mock.When(() => (count % 2 != 0)).Setup( (m) => m.Add(It.IsAny<int>(), It.IsAny<int>())) .Returns(1); Assert.Equal(expected, mock.Object.Add(0, 0)); } MoqStubSample.cs
  • 33. 33Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11 サンプル テスト対象クラス public class JsonWriter : IDisposable { private TextWriter _writer; public JsonWriter(TextWriter writer) { _writer = writer; } public void Dispose() => _writer.Close(); public void Write(string key, string value) { string s = string.Format(@"{{""{0}"":""{1}""}}", key, value); _writer.Write(s); // 引数の型はstring } public void Write(string key, int value) { _writer.Write(@"{{""{0}"":{1}}}", key, value); // 引数の型はstring, string, int } public void Write(string key, double value) { _writer.Write(@"{{""{0}"":{1}}}", key, value); // 引数の型はstring, string, double } } JsonWriter.cs
  • 34. 34Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11 サンプル Callback [Fact(DisplayName = "Callbackの使い方。整形してファイルに出力しているかを確認する")] public void TestCallback() { var mock = new Mock<TextWriter>(); mock.Setup((m) => m.Write(It.IsAny<string>())) .Callback<string>(s => { Assert.Equal(@"{""name"":""テス太郎""}", s); // (1) }); mock.Setup((m) => m.Write(It.IsAny<string>(), It.IsAny<object>(), It.IsAny<int>())) .Callback<string, object, object>((format, name, value) => { Assert.Equal("age", name); // (2) Assert.Equal(13, value); }); mock.Setup((m) => m.Write(It.IsAny<string>(), It.IsAny<object>(), It.IsAny<double>())) .Callback<string, object, object>((format, name, value) => { Assert.Equal("height", name); // (3) Assert.Equal(175.5, value); }); TextWriter tw = mock.Object; var writer = new JsonWriter(tw); writer.Write("name", "テス太郎"); // (1)が呼ばれる writer.Write("age", 13); // (2)が呼ばれる writer.Write("height", 175.5); // (3)が呼ばれる MoqMockSample.cs
  • 35. 35Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11 サンプル Throws [Fact(DisplayName = "Throwsの使い方")] public void TestThrows() { var mock = new Mock<TextWriter>(); mock.Setup( (m) => m.Write(It.IsAny<string>())) // Writeメソッドが呼ばれると .Throws<FileNotFoundException>(); // IOExceptionの派生クラスの // FileNotFoundExeptionを発生させる var writer = new JsonWriter(mock.Object); Assert.ThrowsAny<IOException>( () => { writer.Write("name", "テス太郎"); }); } MoqMockSample.cs
  • 36. 36Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11 サンプル Verify [Fact(DisplayName = "Verifyの使い方")] public void TestVerify() { var mock = new Mock<TextWriter>(); var writer = new JsonWriter(mock.Object); writer.Write("name", "テス太郎"); // 内部でstring, string, stringが呼ばれる。1回目 // Write(string, string, int)は1回も呼ばれていない mock.Verify((m) => m.Write(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>()), Times.Never()); // Write(string, string, int)は最大でも1回しか呼ばれていない(実際は0回) mock.Verify((m) => m.Write(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>()), Times.AtMostOnce()); // Write(string, string, int)は最大でも3回しか呼ばれていない(実際は0回) mock.Verify((m) => m.Write(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>()), Times.AtMost(3)); // Write(string)は一回は呼ばれている mock.Verify((m) => m.Write(It.IsAny<string>()), Times.AtLeastOnce()); // Write(string)は1回だけ呼ばれている mock.Verify((m) => m.Write(It.IsAny<string>()), Times.Once()); writer.Write("name", "テス太郎"); // 内部でstring, string, stringが呼ばれる。2回目 // Write(string)は2回だけ呼ばれている mock.Verify((m) => m.Write(It.IsAny<string>()), Times.Exactly(2)); } MoqMockSample.cs
  • 37. 37Copyright (c) 2017 Eiwa System Management, Inc.2017/3/11 サンプル VerifyAll [Fact(DisplayName = "VerifyAllの使い方")] public void TestVerifyAll() { var mock = new Mock<TextWriter>(); mock.Setup( (m) => m.Write(It.IsAny<string>())); var writer = new JsonWriter(mock.Object); // SetUpした箇所がすべて呼ばれていないときにMockException発生 Assert.ThrowsAny<MockException>( () => { mock.VerifyAll(); }); } MoqMockSample.cs