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

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

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

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

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

Q&A

解決済

2回答

1801閲覧

C# ViewModelのテストについて

yo_si

総合スコア12

C#

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

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

0グッド

0クリップ

投稿2021/11/22 15:46

編集2021/11/23 03:06

前提・実現したいこと

C#での単体テストについてお伺いしたいです。
単体テスト時にLargeViewModelの中のIEnumerable型のUserViewModelにアクセスしたいのですが、「Objectに定義
が含まれていない」といわれます。
ご教授ねがいます!!

環境
ASP.NET MVC
OS Windows10
Visual Studio のバージョン Microsoft Visual Studio Community 2019 Version16.11.3
.NET Framework 4.8

発生している問題・エラーメッセージ

CS1061

'<型>' に '<名前>' の定義が含まれておらず、型 '<型>' の最初の引数を受け付けるアクセス可能な拡張メソッド '<名前>' が見つかりませんでした。using ディレクティブまたはアセンブリ参照が不足しています。

該当のソースコード

Controller

C#

1public ActionResult Index() 2 { 3 LargeViewModel vm = new LargeViewModel(); 4 5 vm.a = aa; 6 vm.bb = bb; 7 8 var connectionString = ConfigurationManager.ConnectionStrings["connectionString"].ConnectionString; 9 using (var conn = new MySqlConnection(connectionString)) 10 { 11 12 var ichiranTable = _userViewModelData.GetAllClients(Param1, Param2, Param3, conn); 13 vm.IchiranTable = ichiranTable.Select(x => new UserViewModel(x)); 14 return View(vm); 15 } 16 }

TestController

C#

1[TestClass] 2 public class LargeControllerTest 3 { 4 [TestMethod] 5 public void Index() 6 { 7 LargeController controller = new LargeController(new DBTest()); 8 9 ViewResult result = controller.Index() as ViewResult; 10 11 12 Assert.IsNotNull(result); 13 //↓IchiranTableにアクセスしたいが、上記エラーメッセージ表示。result.ModelにするとLargeViewModelが指定される 14 Assert.IsInstanceOfType(result.Model.IchiranTable, typeof(IEnumerable<UserViewModel>)); 15 16 17 var model = (result.Model as IEnumerable<UserViewModel>).ToArray(); 18 Assert.IsFalse(model[0].IsInstalled); 19 Assert.IsFalse(model[1].IsInstalled); 20 Assert.IsFalse(model[2].IsInstalled); 21 Assert.IsTrue(model[3].IsInstalled); 22 } 23 }

DBTest

C#

1public IEnumerable<UserViewModel> GetAllClients(string Param1, string Param2, string Param3, MySqlConnection conn) 2 { 3 return new UserViewModel[] 4 { 5 new UserViewModel() { UserId = 0, UserName = "あ", TestFlg = 1}, 6 new UserViewModel() { UserId = 100, UserName = "い", TestFlg = 2 }, 7 new UserViewModel() { UserId = 200, UserName = "う", TestFlg = 3 }, 89 }

LargeViewModel

C#

1public class LargeViewModel 2 { 3 4 public LargeViewModel() 5 { 6 7 } 8 public IEnumerable<SelectListItem> AList { get; set; } 9 10 public IEnumerable<SelectListItem> BList { get; set; } 11 12 public IEnumerable<SelectListItem> CList { get; set; } 13 14 public IEnumerable<UserViewModel> IchiranTable { get; set; } 15 16 public string a { get; set; } 17 18 public string b { get; set; } 19 20 public string c { get; set; } 21 }

UserViewModel

C#

1public class UserViewModel 2 { 3 public UserViewModel() 4 { 5 6 } 7 public UserViewModel(UserViewModel x) 8 { 9 UserId = x.UserId; 10 UserName = x.UserName; 11 TestFlg = x.TestFlg; 12 IsInstalled = (x.TestFlg == (int)TestType.Installed); 13 } 14 public int UserId { get; set; } 15 16 public string UserName { get; set; } 17 18 public int TestFlg { get; set; } 19 20 public bool IsInstalled { get; set; } 21 22 } 23 24 public enum TestType 25 { 26 Test = 9, 27 Test1 = 1, 28 Test2 = 2, 29 Installed = 3, 30 Test3 = 4, 31 Test4 = 0 32 }

試したこと

補足情報(FW/ツールのバージョンなど)

情報不足している場合は、仰ってください。

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

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

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

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

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

gentaro

2021/11/22 15:51

そもそも論だけど「単体」テストならDBにアクセスしている部分を抽象化して切り離さないとダメじゃね? あとデバッグしてテスト対象のコード側で値がちゃんと取れてるかどうか確認してるんだろうか。
yo_si

2021/11/22 16:12 編集

テスト用のDBにアクセスして、result.Model直下にIchiranTableがあるのを(値を取得できているのも)確認できているのですが、IchiranTableにアクセスすると定義されていないといわれております。
退会済みユーザー

退会済みユーザー

2021/11/22 22:20

何を作っているか (WPF? ASP.NET MVC? その他?) と開発環境 (OS, Visual Studio のバージョン、Core か .NET Framework どっちなのかとそのバージョンなど) を書いてください。
yo_si

2021/11/23 00:01

何を作っているか (WPF? ASP.NET MVC? その他?) →ASP.NET MVC 開発環境 (OS, Visual Studio のバージョン、Core か .NET Framework どっちなのかとそのバージョンなど) を書いてください。 →OS Windows10 →Visual Studio のバージョン Microsoft Visual Studio Community 2019 Version16.11.3 →.NET Framework 4.8
退会済みユーザー

退会済みユーザー

2021/11/23 00:45

上の情報は質問欄を編集して追記願います。ここコメント欄は「質問への追記・修正の依頼」の場所ですし、初期画面では閉じていて読まない人もいますので。 ASP.NET のタグをつけてください。モデルの定義も追記してください。
yo_si

2021/11/23 01:32

修正しました
退会済みユーザー

退会済みユーザー

2021/11/23 02:33

単体テスト、O/R マッパー Dapper、DI コンテナ Autofac とか言われて、何故単体テストが期待通りに動かないかという話ですと自分には分からない部分が多くてお手上げです。単体テストの話ではなく、提示された Model とダミーの GetAllClients メソッドだけを使って Controller が期待通り動くのかという話ならフォローできそうです。それでもよければその旨返事ください。 それではダメならこのコメントはスルーしてください。すみませんが自分は撤退します。他の方の回答をお待ちください。
yo_si

2021/11/23 03:11

はい、期待通りTestControllerが動くようにしていただけることをのぞんでおります。
退会済みユーザー

退会済みユーザー

2021/11/23 04:50

質問者さんのコードをコピペして、間違いは直して試してみましたが、return View(vm); の vm には期待通りの結果が得られていました。もちろん質問に書いてあったような例外も出ません。ということで、「単体テスト」の方に何か問題がありそうです。
退会済みユーザー

退会済みユーザー

2021/11/23 04:53

回答欄に検証に使ったコードと取得できた vm の画像を貼っておきます。
TN8001

2021/11/23 10:09

何にもわかってないですけど、キャストがいるってだけじゃないんですか? ((LargeViewModel)result.Model).IchiranTable
yo_si

2021/11/23 13:15

TN8001さん キャストが問題でした。ありがとうございます!!
退会済みユーザー

退会済みユーザー

2021/11/23 14:01

TestController というのはどのようにして作ったのですか?
guest

回答2

0

自己解決

TN8001さんのコメント通り
TestControllerにて((LargeViewModel)result.Model).IchiranTableのようにキャストして解決。

投稿2021/11/23 13:20

yo_si

総合スコア12

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

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

退会済みユーザー

退会済みユーザー

2021/11/23 14:02

TestController というのはどのようにして作ったのですか?
guest

0

質問に対する 2021/11/23 13:53 の私のコメントで「回答欄に検証に使ったコードと取得できた vm の画像を貼っておきます」と書いた件です。

質問者さんのコードをコピペして、間違いは直して試してみましたが、return View(vm); の vm には期待通りの結果が得られていました。もちろん質問に書いてあったような例外も出ません。

ということで、「単体テスト」の方に何か問題がありそうです。

Model と UserViewModelData メソッド

using System.Collections.Generic; using System.Web.Mvc; using MySql.Data.MySqlClient; namespace Mvc5App3.Models { public class LargeViewModel { public LargeViewModel() { } public IEnumerable<SelectListItem> AList { get; set; } public IEnumerable<SelectListItem> BList { get; set; } public IEnumerable<SelectListItem> CList { get; set; } public IEnumerable<UserViewModel> IchiranTable { get; set; } public string a { get; set; } public string b { get; set; } public string c { get; set; } } public class UserViewModel { public UserViewModel() { } public UserViewModel(UserViewModel x) { UserId = x.UserId; UserName = x.UserName; TestFlg = x.TestFlg; IsInstalled = (x.TestFlg == (int)TestType.Installed); } public int UserId { get; set; } public string UserName { get; set; } public int TestFlg { get; set; } public bool IsInstalled { get; set; } } public enum TestType { Test = 9, Test1 = 1, Test2 = 2, Installed = 3, Test3 = 4, Test4 = 0 } public class UserViewModelData { public IEnumerable<UserViewModel> GetAllClients(string Param1, string Param2, string Param3, MySqlConnection conn) { return new UserViewModel[] { new UserViewModel() { UserId = 0, UserName = "あ", TestFlg = 1}, new UserViewModel() { UserId = 100, UserName = "い", TestFlg = 2 }, new UserViewModel() { UserId = 200, UserName = "う", TestFlg = 3 } }; } } }

Controller

using System.Linq; using System.Web.Mvc; using Mvc5App3.Models; using MySql.Data.MySqlClient; namespace Mvc5App3.Controllers { public class TestController : Controller { // GET: Test public ActionResult Index() { LargeViewModel vm = new LargeViewModel(); UserViewModelData _userViewModelData = new UserViewModelData(); vm.a = "aa"; vm.b = "bb"; string Param1 = "Param1"; string Param2 = "Param2"; string Param3 = "Param3"; var connectionString = "server=localhost;user id=root;password=********;database=world"; using (var conn = new MySqlConnection(connectionString)) { var ichiranTable = _userViewModelData.GetAllClients(Param1, Param2, Param3, conn); vm.IchiranTable = ichiranTable.Select(x => new UserViewModel(x)); return View(vm); } } } }

取得できた vm の内容:

イメージ説明

投稿2021/11/23 05:03

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

yo_si

2021/11/23 06:00

ありがとうございます!!
yo_si

2021/11/23 06:05 編集

TestControllerに記載しているエラーの内容はなぜ表示されるのか。まではわかりませんか? 少しでも心当たりあればご教授ねがいます。
退会済みユーザー

退会済みユーザー

2021/11/23 06:38

何故単体テストが期待通りに動かないかは自分には分からない部分が多くてお手上げです。
退会済みユーザー

退会済みユーザー

2021/11/23 09:20 編集

質問に書かれている TestController コードは、Model / Controller のコードをベースに作ったものと違うのではないですか? 何にしても、普通に動かすと問題なくて、テストコードを作って動かすとダメと言うのでは、一体何をテストしているのか分からないということになりますね。 上の検証で例外が出ればそこから何か分かるかもしれないと思っていたのですが・・・
yo_si

2021/11/23 13:17

キャストができていないことが問題でした。 ご協力ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問