質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

MVVM

MVVM(Model View ViewModel)は構築上のデザインパターンで、表現ロジック(ViewModel)によってデータ(Model)からページ(View)を分離させます。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

1回答

2167閲覧

単体テストにおけるスタブ、ドライバの作成方法

---stax---

総合スコア148

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

MVVM

MVVM(Model View ViewModel)は構築上のデザインパターンで、表現ロジック(ViewModel)によってデータ(Model)からページ(View)を分離させます。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

0クリップ

投稿2017/12/06 06:44

表題の件で質問させてください
現在アプリを作成し、単体テストを行っています
その中でスタブを使いたい部分が出てきたのですが、調べかたが悪いためかドライバやスタブの概要は記載されていても実装の仕方がわからず、そもそもそういうクラスがあるのか、実装にあたって何か特殊な記載方法があるのかどうかすらわからず悩んでおりアドバイスをいただきたいです

以下現在取り組んでいる内容です
MVVMにおけるModelクラスの構造が以下のような流れになっています

Model① 
↓(①で加工されたデータを引数で渡しModel②のメソッドを呼び出す)
Model②
↓(②で加工されたデータを引数で渡しModel③のメソッドを呼び出す)
Model③
(①②で加工されたデータを受け取り最終加工)

知識が浅いためこのような構造になっているのですが、Model①のテストを行うとModel③まで到達します
Model①クラスのみのテストを行うためにスタブを使えるといいのかなと考えています
もし考え方がおかしい部分があればご指摘いただけると幸いです
宜しくお願い致します

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

こんにちは。

正しいと思います。
Model1のテストをするにあたってはModel2以降はスタブを使ったほうが良いと思います。

ドライバについてVisual Studioに統合されているユニットテストの仕組みなどがその役割を果たしていると思います。
PrivateなアクセスについてはPrivateObjectが提供されているので直接アクセスすることが出来ます。

Microsoft Fakes や Moq などのライブラリを活用するとスタブ利用しやすいと思います。
そもそもDI出来るようにしておくのが望ましいですが。

投稿2017/12/07 02:28

Tak1wa

総合スコア4791

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

---stax---

2017/12/07 04:05

回答ありがとうございます MoqやFakesなど初めて知りました インターフェースの理解が浅いのでまずはMoqを使用してみます (ラムダ式も理解できていませんが・・・) まずは”メソッドが”呼び出されたか”を目標にしてみます >>そもそもDI出来るようにしておくのが望ましいですが。 まだまだ理解が浅くオブジェクト指向が何たるかも習得しきれていませんが やはりクラス間で処理が続いてしまうのはクラスを分けている意味がなく、良くないのですね
---stax---

2017/12/07 04:50

重ねての質問で申し訳ないのですが教えてください 今回はModel1のテストを行う基準として、Model1内のsarch1というメソッドが実行されるとModel2のsarch2というメソッドに引数を渡して実行します。このため、Model1のテストではModel2のsarch2が呼ばれた、という事をテスト基準にしたいのですが、SetupをModel1.sarch1とした場合Returnには戻り値などはなく、単純にメソッドが呼ばれたことを確認するにはどのように記述すればよいでしょうか?Verifyを使うにもSetupで指定する必要があると理解したのですが間違えているでしょうか?コードも見せずに質問して答えにくいと思いますが、よろしければアドバイスお願いいたします
---stax---

2017/12/08 01:02

ありがとうございます 引数等は省略していますが以下のコードで実装出来ました ただ、一部理解があっているのか確認させていただいてもよろしいでしょうか コードや定義が分からない状態で申し訳ありません このテストメソッドはModel1クラスのテストです 自分で書いたのですが特に②、③の理解があっているのかあいまいです ③に関してはvar field = sarch.GetField("model2")で初めは書いたのですがエラーとなったため書き直したのですが これはMockで指定しているModel2と紐付いていないためでしょうか? ---確認したい箇所--- ①Mock<Model2> mock = new Mock<Model2>(); ・Model2クラスのモックを作成 ②var sarch = new PrivateObject(_model1); ・_model1(Model1のクラスのインスタンス)内にあるPrivateオブジェクトをsarchを用いて使用出来るようにする ③sarch.SetFieldOrProperty("model2", mock.Object); ・sarch.SetFieldOrProperty(_model1のPrivateオブジェクト利用権利のようなもの?)でmodel2というPrivateオブジェクト をmock(Model2クラスのモック)で使用できるようにする ※model2はModel1クラスが持っているModel2クラスインスタンスです ④_sarch1.sarch1(); テスト対象のメソッド実行 ⑤mock.Verify(x => x.SarchCheck2_1(), Times.Once()); mock.Verifyで④_sarch1.sarch1();の処理から呼ばれるはずのModel2クラスのSarchCheck2_1()が一度呼ばれたかどうか確認 ---以下コード--- Model1 _model1 = new Model1(); Model2 _model2 = new Model2(); [TestMethod()] public void sarch1Test() { ①Mock< Model2> mock = new Mock< Model2>(); ②var sarch = new PrivateObject(_model1);      ③sarch.SetFieldOrProperty("model2", mock.Object);      //var field = sarch.GetField("model2") ④_sarch1.sarch1(); ⑤mock.Verify(x => x.SarchCheck2_1(), Times.Once()); } ①Mock<Sarch2> mock = new Mock<Sarch2>(); Sarch2クラスのモックを作成 ②var sarch = new PrivateObject(_sarch1); _sarch1(Sarch1のクラスのインスタンス) Sarch1 _sarch1 = new Sarch1(); Sarch2 _sarch2 = new Sarch2(); [TestMethod()] public void sarch1Test() { ①Mock<Sarch2> mock = new Mock<Sarch2>(); ②var sarch = new PrivateObject(_sarch1);      ③//var field = sarch.GetField("sarch2"); ③//sarch.SetFieldOrProperty("sarch2", mock.Object); ④_sarch1.sarch1(); ⑤mock.Verify(x => x.SarchCheck2_1(), Times.Once()); }
---stax---

2017/12/08 01:14

確認したい事の項目のコードの下に書いてる・から始まる部分が自分の今の理解です
Tak1wa

2017/12/08 06:57

クラス名とメソッド名が混在しててよくわからないですね…。 PrivateObjectを使っているのはなぜですか? Model2はプロパティか、コンストラクタなどでインジェクションできるようにしておいたほうがテストしやすいですよ。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問