私は Asp.net MVC 5 プロジェクトに取り組んでおり、コントローラー内でカスタム プリンシパルを返すためのモックを設定しようとしています。検索して、提案されたさまざまなアプローチを試しましたが、どれも機能しません。
すべてのコントローラーが継承する BaseController があります。BaseController には、ゲッターで HttpContext.User を返す User プロパティがあります。HttpContext.user は、プロジェクト内で呼び出されると値を返しますが、ユニット テスト プロジェクトから呼び出されると null を返します。
ベースコントローラ
public class BaseController : Controller
{
protected virtual new CustomPrincipal User
{
get { return HttpContext.User as CustomPrincipal; } ***<== Line with issue***
}
}
カスタムプリンシパル
public class CustomPrincipal : IPrincipal, ICustomPrincipal
{
public IIdentity Identity { get; private set; }
public string UserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public bool IsStoreUser { get; set; }
public CustomPrincipal(string username)
{
this.Identity = new GenericIdentity(username);
}
}
コントローラ
public class DocumentsController : BaseController
{
public ViewResult ViewDocuments()
{
var userType = User.IsStoreUser ? UserType.StoreUser : UserType.Corporate; ***<== User is null when calling from a unit test.***
}
}
テストケース
[Test]
public void ViewDocuments_WhenCalled_ShouldReturnViewModel()
{
// Arrange
var principal = new CustomPrincipal("2038786");
principal.UserId = "2038786";
principal.FirstName = "Test";
principal.LastName = "User";
principal.IsStoreUser = true;
var _mockController = new Mock<DocumentsController>(new UnitOfWork(_context)) { CallBase = true };
_mockController.Setup(u => u.User).Returns(principal); ***<== Error - "Invalid setup on a non-virtual (overridable in VB) member: u => u.User"***
// Act
var result = _controller.ViewDocuments();
}
nUnit と Moq を使用してモック オブジェクトを作成していますが、何が間違っているのかわかりません。テストで作成したカスタム プリンシパル オブジェクトの IsStore の値を返すには、DocumentControl の User.IsStore の戻りをモックする必要があります。
ベストアンサー1
模擬HTTPコンテキストを作成する
private class MockHttpContext : HttpContextBase {
private readonly IPrincipal user;
public MockHttpContext(IPrincipal principal) {
this.user = principal;
}
public override IPrincipal User {
get {
return user;
}
set {
base.User = value;
}
}
}
それに応じてテストを調整します。
[Test]
public void ViewDocuments_WhenCalled_ShouldReturnViewModel() {
// Arrange
var principal = new CustomPrincipal("2038786");
principal.UserId = "2038786";
principal.FirstName = "Test";
principal.LastName = "User";
principal.IsStoreUser = true;
var mockUoW = new Mock<IUnitOfWork>();
//...setup UoW dependency if needed
var controller = new DocumentsController(mockUoW.Object);
controller.ControllerContext = new ControllerContext {
Controller = controller,
HttpContext = new MockHttpContext(principal)
};
// Act
var result = controller.ViewDocuments();
//Assert
//...assertions
}
テスト対象のシステムをモックしないでください。その依存関係をモックしてください。