私の単体テストに必要なHttpContext
をシミュレートするのに苦労しています。ユニットテスト用のHttpContextを作成するにはどうすればよいですか?
SessionManager
インターフェイスを使用してMvcコントローラからセッションの制御を抽象化し、これをCookieSessionManager
というクラスで実装しました。 (初期開発段階)。
CookieSessionManager
は、注入されたシングルトンHttpContextAccessor
(Startup.cs ConfigureServices内)を使用してHttpContext
を使用します。
私は、app.UseCookieAuthentication
でStartup.csに設定されているCookie認証を使用しています。私が注入さMockSessionManager
クラスと私のAccountController
クラスの仕事のために書かれている
MSUnit
テストが期待通りにデバッグモードで
テストこのマニュアルでは動作します。
私の実際の問題は、私がCookieSessionManager
クラスのために書いたユニットテストです。私は以下のようにHttpContext
をセットアップしようとしました。
[TestClass]
public class CookieSessionManagerTest
{
private IHttpContextAccessor contextAccessor;
private HttpContext context;
private SessionManager sessionManager;
[TestInitialize]
public void Setup_CookieSessionManagerTest()
{
context = new DefaultHttpContext();
contextAccessor = new HttpContextAccessor();
contextAccessor.HttpContext = context;
sessionManager = new CookieSessionManager(contextAccessor);
}
エラー
しかしsessionManager.Login(CreateValidApplicationUser());
への呼び出しはIsAuthenticated
フラグとCookieSessionManager_Login_ValidUser_Authenticated_isTrue
が失敗したテストを設定するためには表示されません。
[TestMethod]
public void CookieSessionManager_Login_ValidUser_Authenticated_isTrue()
{
sessionManager.Login(CreateValidApplicationUser());
Assert.IsTrue(sessionManager.isAuthenticated());
}
public ApplicationUser CreateValidApplicationUser()
{
ApplicationUser applicationUser = new ApplicationUser();
applicationUser.UserName = "ValidUser";
//applicationUser.Password = "ValidPass";
return applicationUser;
}
テスト名:CookieSessionManager_Login_ValidUser_Authenticated_isTrue
:ライン43試験結果:失敗した試験時間:0:00:00.0433169
結果のStackTrace:ClaimsWebAppTests.Identity.CookieSessionManagerTest.CookieSessionManager_Login_ValidUser_Authenticated_isTrueで()
CookieSessionManagerTest.cs:46行目結果メッセージ:Assert.IsTrueが失敗しました。
MY CODE
SessionManagerの
using ClaimsWebApp.Models;
namespace ClaimsWebApp.Identity
{
public interface SessionManager
{
bool isAuthenticated();
void Login(ApplicationUser applicationUser);
void Logout();
}
}
CookieSessionManager
using ClaimsWebApp.Identity;
using ClaimsWebApp.Models;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Security.Claims;
namespace ClaimsWebApp
{
public class CookieSessionManager : SessionManager
{
private List<ApplicationUser> applicationUsers;
private IHttpContextAccessor ContextAccessor;
private bool IsAuthenticated;
public CookieSessionManager(IHttpContextAccessor contextAccessor)
{
this.IsAuthenticated = false;
this.ContextAccessor = contextAccessor;
IsAuthenticated = ContextAccessor.HttpContext.User.Identity.IsAuthenticated;
applicationUsers = new List<ApplicationUser>();
applicationUsers.Add(new ApplicationUser { UserName = "ValidUser" });
}
public bool isAuthenticated()
{
return IsAuthenticated;
}
public void Login(ApplicationUser applicationUser)
{
if (applicationUsers.Find(m => m.UserName.Equals(applicationUser.UserName)) != null)
{
var identity = new ClaimsIdentity(new[] {
new Claim(ClaimTypes.Name, applicationUser.UserName)
},
"MyCookieMiddlewareInstance");
var principal = new ClaimsPrincipal(identity);
ContextAccessor.HttpContext.Authentication.SignInAsync("MyCookieMiddlewareInstance", principal);
IsAuthenticated = ContextAccessor.HttpContext.User.Identity.IsAuthenticated;
}
else
{
throw new Exception("User not found");
}
}
public void Logout()
{
ContextAccessor.HttpContext.Authentication.SignOutAsync("MyCookieMiddlewareInstance");
IsAuthenticated = ContextAccessor.HttpContext.User.Identity.IsAuthenticated;
}
}
}
スタート
using ClaimsWebApp.Identity;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace ClaimsWebApp
{
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddScoped<SessionManager, CookieSessionManager>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole();
app.UseCookieAuthentication(new CookieAuthenticationOptions()
{
AuthenticationScheme = "MyCookieMiddlewareInstance",
LoginPath = new PathString("/Account/Unauthorized/"),
AccessDeniedPath = new PathString("/Account/Forbidden/"),
AutomaticAuthenticate = true,
AutomaticChallenge = true
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Account}/{action=Login}/{id?}");
});
}
}
}
CookieSessionManagerTest up.cs。CS
using ClaimsWebApp;
using ClaimsWebApp.Identity;
using ClaimsWebApp.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace ClaimsWebAppTests.Identity
{
[TestClass]
public class CookieSessionManagerTest
{
private IHttpContextAccessor contextAccessor;
private HttpContext context;
private SessionManager sessionManager;
[TestInitialize]
public void Setup_CookieSessionManagerTest()
{
context = new DefaultHttpContext();
contextAccessor = new HttpContextAccessor();
contextAccessor.HttpContext = context;
sessionManager = new CookieSessionManager(contextAccessor);
}
[TestMethod]
public void CookieSessionManager_Can_Be_Implemented()
{
Assert.IsInstanceOfType(sessionManager, typeof(SessionManager));
}
[TestMethod]
public void CookieSessionManager_Default_Authenticated_isFalse()
{
Assert.IsFalse(sessionManager.isAuthenticated());
}
[TestMethod]
public void CookieSessionManager_Login_ValidUser_Authenticated_isTrue()
{
sessionManager.Login(CreateValidApplicationUser());
Assert.IsTrue(sessionManager.isAuthenticated());
}
public ApplicationUser CreateValidApplicationUser()
{
ApplicationUser applicationUser = new ApplicationUser();
applicationUser.UserName = "ValidUser";
//applicationUser.Password = "ValidPass";
return applicationUser;
}
public ApplicationUser CreateInValidApplicationUser()
{
ApplicationUser applicationUser = new ApplicationUser();
applicationUser.UserName = "InValidUser";
//applicationUser.Password = "ValidPass";
return applicationUser;
}
}
}
TestServerを使用して調査しましたか? https://docs.asp.net/en/latest/testing/integration-testing.html – Brad
ありがとう@ブラッド、私はこれがまさに私が探しているものだと思います。私は実装の問題であるときに問題から単体テストを作るのが難しいです。 –
TypeMockアイソレータでHttpContextをモックすることが可能です。例:https://www.typemock.com/docs?book=Isolator&page=Documentation%2FHtmlDocs%2Fsample1fakinghttpcontextandmodelstate.htm –