Я создаю приложение ASP.NET с контроллером Web Api 2 с аутентификацией.Приложение работает хорошо, я проверял через Почтальон!Я хочу создать модульные тесты с HttpServer / HttpClient, но он не работает.
До этого я не создавал ничего подобного.
AccountController.cs
[RoutePrefix("api/account")]
public class AccountController : ApiController
{
private ApplicationUserManager appUserManager = null;
protected ApplicationUserManager AppUserManager
{
get
{
return appUserManager ?? Request.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
appUserManager = value;
}
}
private IAuthenticationManager Authentication
{
get { return Request.GetOwinContext().Authentication; }
}
public AccountController()
{
}
public AccountController(ApplicationUserManager userManager)
{
AppUserManager = userManager;
}
[HttpGet]
[Route("users")]
public IHttpActionResult GetUsers()
{
return Ok(AppUserManager.Users.ToList());
}
[HttpGet]
[Route("hello")]
public IHttpActionResult Hello()
{
return Ok();
}
...
IdentityConfig.cs
public class ApplicationUserManager : UserManager<ApplicationUser>
{
public ApplicationUserManager(IUserStore<ApplicationUser> store)
: base(store)
{
}
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
var appDbContext = context.Get<ApplicationDbContext>();
var appUserManager = new ApplicationUserManager(new UserStore<ApplicationUser>(appDbContext));
return appUserManager;
}
}
public class ApplicationRoleManager : RoleManager<IdentityRole>
{
public ApplicationRoleManager(IRoleStore<IdentityRole, string> roleStore)
: base(roleStore)
{
}
public static ApplicationRoleManager Create(IdentityFactoryOptions<ApplicationRoleManager> options, IOwinContext context)
{
var appDbContext = context.Get<ApplicationDbContext>();
var appRoleManager = new ApplicationRoleManager(new RoleStore<IdentityRole>(appDbContext));
return appRoleManager;
}
}
Startup.Auth
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
});
}
}
WebApiConfig.cs
public static void Register(HttpConfiguration config)
{
Database.SetInitializer<ApplicationDbContext>(new DbInitializer());
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
Startup.cs
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
}
}
AccountControllerTests.cs
public class AccountControllerTests
{
private HttpServer server;
public AccountControllerTests()
{
var config = new HttpConfiguration();
WebApiConfig.Register(config);
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
server = new HttpServer(config);
}
public HttpRequestMessage CreateRequest(string url, HttpMethod method)
{
var request = new HttpRequestMessage();
request.RequestUri = new Uri(url);
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
request.Method = method;
return request;
}
private HttpRequestMessage CreateRequest<T>(string url, HttpMethod method, T content) where T : class
{
var request = CreateRequest(url, method);
request.Content = new ObjectContent<T>(content, new JsonMediaTypeFormatter());
return request;
}
public void Dispose()
{
if (server != null)
{
server.Dispose();
}
}
[TestMethod]
public async Task TestGetUsersAsync()
{
var client = new HttpClient(server);
var request = CreateRequest("http://localhost/api/account/users", HttpMethod.Get);
using (var response = await client.SendAsync(request))
{
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
request.Dispose();
}
[TestMethod]
public async Task TestHelloAsync()
{
var client = new HttpClient(server);
var request = CreateRequest("http://localhost/api/account/hello", HttpMethod.Get);
using (var response = await client.SendAsync(request))
{
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
request.Dispose();
}
...
Фактические результаты:
TestGetUsersAsync()
- сбой
TestHelloAsync()
- пропуск
Я проверил: AppUserManager
в AccountController
равно нулю Request.GetOwinContext()
равно нулю
В чем дело?Ошибка происходит при доступе к базе данных;нужно как-то установить контекст.
Новая информация.HttpContext.Current будет нулевым.HttpContext основан на IIS и не будет установлен при самостоятельном размещении с OWIN. source Не должен использоваться в программе HttpContext.Я изменил:
protected ApplicationUserManager AppUserManager
{
get
{
return appUserManager ?? Request.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
appUserManager = value;
}
}
на
protected ApplicationUserManager AppUserManager { get; set; } = new ApplicationUserManager(new UserStore<ApplicationUser>(new ApplicationDbContext()));
все это работает, но я не знаю, как изменить:
private IAuthenticationManager Authentication => Request.GetOwinContext().Authentication;
???