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

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

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

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

ASP.NET

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

Q&A

解決済

1回答

3175閲覧

MoqのSetupで引数を2つ指定すると、正しくSetupをしてくれない場合がある

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

ASP.NET

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

0グッド

0クリップ

投稿2021/04/28 06:35

編集2021/05/09 11:26

C#、ASP.NET Core MVCでユニットテストを作成しています。MoqのSetupで引数を2つ指定すると、正しくSetupをしてくれない場合があり、困っています。
どなたかご教授お願いします。

わかっていることとしては、

①Contollerの引数をListで渡す時
this._userCheckService.IsCheckedAsyncの引数が
1つの時はtrueを返していた。2つの時にfalseになっていました。

②Contollerの引数を単一データで渡す時
this._userCheckService.IsCheckedAsyncの引数が2つでも、問題なくtrueになりました。

①の作り方をした時のみ、現象が発生しています。

(追記)
開発環境: Windows10 Pro, Visual Studio Professional 2019, .NET 5

C#

1using ApplicationService; 2using DomainModel; 3using DomainService; 4using Microsoft.AspNetCore.Http; 5using Microsoft.AspNetCore.Mvc; 6using Microsoft.Extensions.Logging; 7using Moq; 8using System; 9using System.Collections.Generic; 10using System.Linq; 11using System.Security.Claims; 12using System.Threading.Tasks; 13using UserInterface.Controllers; 14using Xunit; 15 16namespace Test.Controllers.Transaction { 17 18 public class TestsControllerTest : Controller { 19 private Mock<ILogger<TestsController>> _loggerMock = null; 20 private Mock<IUserCheckService> _userCheckServiceMock = null; 21 22 private ClaimsPrincipal _user = null; 23 private TestsController _controller = null; 24 25 public TestsControllerTest() { 26 this._loggerMock = new Mock<ILogger<TestsController>>(); 27 this._userCheckServiceMock = new Mock<IUserCheckService>(); 28 29 this._user = new ClaimsPrincipal(new ClaimsIdentity(new Claim[] { 30 new Claim(ClaimTypes.Name, "Administrator"), 31 new Claim(ClaimTypes.Role, "Administrator") 32 }, "mock")); 33 34 // この場合はtrueを返す 35 // this._userCheckServiceMock.Setup(e => e.IsCheckedAsync(this._user)).ReturnsAsync(true); 36 37 // この方法だとうまくいかなかった 38 this._userCheckServiceMock.Setup(e => e.IsCheckedAsync(this._user, null)).ReturnsAsync(true); 39 40 this._controller = new TestsController( 41 this._loggerMock.Object, 42 this._userCheckServiceMock.Object 43 ); 44 45 this._controller.ControllerContext = new ControllerContext() { 46 HttpContext = new DefaultHttpContext() { User = this._user } 47 }; 48 } 49 50 [Fact] 51 public async Task<int> RegisterAsync() { 52 // 適当にnullにしています。 53 var result = await this._controller.Register(null); 54 55 return 1; 56 } 57 } 58}

C#

1using Microsoft.AspNetCore.Authorization; 2using Microsoft.AspNetCore.Mvc; 3using Microsoft.AspNetCore.Http; 4using Microsoft.Extensions.Logging; 5using System; 6using System.Collections.Generic; 7using System.Linq; 8using System.Net; 9using System.Threading.Tasks; 10using ApplicationService; 11using DomainModel; 12using DomainService; 13using System.Security.Claims; 14using Microsoft.AspNetCore.Identity; 15 16namespace UserInterface.Controllers { 17 public class TestsController : Controller { 18 private readonly ILogger<TestsController> _logger; 19 private readonly IUserCheckService _userCheckService; 20 21 public TestsController(ILogger<TestsController> logger, IUserCheckService userCheckService) { 22 this._logger = logger; 23 this._userCheckService = userCheckService; 24 } 25 26 // 説明のため属性は省略しています。 27 public async Task<IActionResult> Register(IList<Test> tests) { 28 // ①Contollerの引数をListで渡す時 29 // this._userCheckService.IsCheckedAsyncの引数が 30 // 1つの時はtrueを返していた。 31 // 2つの時にfalseになってしまう。 32 33 // true 34 bool isCheckedUser1 = Task.FromResult(await this._userCheckService.IsCheckedAsync(this.User)).Result; 35 36 // false 37 bool isCheckedUser2 = Task.FromResult(await this._userCheckService.IsCheckedAsync(this.User, null)).Result; 38 39 // ②Contollerの引数を単一データで渡す時 40 // this._userCheckService.IsCheckedAsyncの引数が2つでも、trueになりました。 41 } 42 } 43}

C#

1using System; 2using System.Security.Claims; 3using System.Threading.Tasks; 4using DomainModel; 5 6namespace DomainService { 7 public interface IUserCheckService { 8 Task<bool> IsCheckedAsync(ClaimsPrincipal user); 9 Task<bool> IsCheckedAsync(ClaimsPrincipal user, Project project); 10 } 11}

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2021/04/28 07:46 編集

何を作っているかと開発環境を質問欄を編集して追記してください。現状、ASP.NET の何かを、開発言語 C# で作っているということがタグから分かるぐらいです。コードを読めばわかるとは言わないでください。あなたが質問の一行目に書けば済むことなのですから。
退会済みユーザー

退会済みユーザー

2021/04/28 08:08

コメントありがとうございます。 1行目に追記させていただきました。よろしくお願いします。
退会済みユーザー

退会済みユーザー

2021/04/29 01:51

> 1行目に追記させていただきました。よろしくお願いします。 開発環境(OS, Visual Studio, Core のバージョンなど)を書かないのは何か理由があるのですか?
退会済みユーザー

退会済みユーザー

2021/04/29 02:04

コードを拝見しました。残念ながら内容が分からないし問題を再現することもできないので回答できないのですが、ざっと見気になった点を書いておきます。 > bool isCheckedUser1 = Task.FromResult(await this._userCheckService.IsCheckedAsync(this.User)).Result; > bool isCheckedUser2 = Task.FromResult(await this._userCheckService.IsCheckedAsync(this.User, null)).Result; 同期・非同期を混ぜるという典型的なデッドロックパターンにように見えます。戻り値が取得できたようなのでデッドロックにはなってなくて問題の原因ではなさそうですが、単純に以下のようにすべきではないでしょうか? bool isCheckedUser1 = await this._userCheckService.IsCheckedAsync(this.User); bool isCheckedUser2 = await this._userCheckService.IsCheckedAsync(this.User, null);
退会済みユーザー

退会済みユーザー

2021/04/29 05:29

開発環境について追記させて頂きました。 Windows10 Pro, Visual Studio Professional 2019, .NET 5 デッドロックパターンについて間違い指摘ありがとうございます。 bool isCheckedUser1 = await this._userCheckService.IsCheckedAsync(this.User); 修正はしましたが、これが原因ではなかったです。 他の原因についても調べているところです。
guest

回答1

0

ベストアンサー

原因はわからないのですが、nullまたは空オブジェクトではだめで、It.IsAny<T>()を使うことで解決しました。

C#

1using ApplicationService; 2using DomainModel; 3using DomainService; 4using Microsoft.AspNetCore.Http; 5using Microsoft.AspNetCore.Mvc; 6using Microsoft.Extensions.Logging; 7using Moq; 8using System; 9using System.Collections.Generic; 10using System.Linq; 11using System.Security.Claims; 12using System.Threading.Tasks; 13using UserInterface.Controllers; 14using Xunit; 15 16namespace Test.Controllers.Transaction { 17 18 public class TestsControllerTest : Controller { 19 private Mock<ILogger<TestsController>> _loggerMock = null; 20 private Mock<IUserCheckService> _userCheckServiceMock = null; 21 22 private ClaimsPrincipal _user = null; 23 private TestsController _controller = null; 24 25 public TestsControllerTest() { 26 this._loggerMock = new Mock<ILogger<TestsController>>(); 27 this._userCheckServiceMock = new Mock<IUserCheckService>(); 28 29 // nullまたは空オブジェクトではだめで、It.IsAny<T>()を使うことで解決しました。 30 this._userCheckServiceMock.Setup(e => e.IsCheckedAsync(It.IsAny<ClaimsPrincipal>, It.IsAny<Project>())).ReturnsAsync(true); 31 32 this._controller = new TestsController( 33 this._loggerMock.Object, 34 this._userCheckServiceMock.Object 35 ); 36 37 // ダミーのUserはこれで対応 38 this._user = new ClaimsPrincipal(new ClaimsIdentity(new Claim[] { 39 new Claim(ClaimTypes.Name, "Administrator"), 40 new Claim(ClaimTypes.Role, "Administrator") 41 }, "mock")); 42 43 this._controller.ControllerContext = new ControllerContext() { 44 HttpContext = new DefaultHttpContext() { User = this._user } 45 }; 46 } 47 48 [Fact] 49 public async Task<int> RegisterAsync() { 50 // 適当にnullにしています。 51 var result = await this._controller.Register(null); 52 53 return 1; 54 } 55 } 56}

投稿2021/04/30 07:57

編集2021/05/09 11:29
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問