unit-testing - 启用两因素身份验证时的 ASP.Net Core XUnit 集成测试
问题描述
我正在为 API 使用 ASP.Net Core 3.1 开发一个 Angular Web 应用程序。
到目前为止,我已经使用 Custom WebApplicationFactory 编写了一些集成单元测试来创建测试服务器。
所有测试都使用 HttpClient 对在 Custom WebApplicationFactory 下运行的 API 进行 GET 和 POST。大多数这些测试最初执行登录以获得用于后续请求的令牌。
我想在应用程序中添加两因素身份验证,但这将不可避免地破坏任何测试,因为他们无法获取将通过电子邮件发送的六位数代码。
这是当前未实施 MFA 的测试的样子。有没有办法可以为测试提供 MFA 代码,以便它可以继续执行测试?
我是否只需要为未启用 MFA 的用户播种?我实际上希望所有用户都在生产中启用 MFA。
非常感谢
using Xunit;
using System.Threading.Tasks;
using MyCompany.ViewModels.Authentication;
using MyCompany.StaffPortal.Tests.Shared;
using StaffPortal;
using Newtonsoft.Json;
using MyCompany.ServiceA.ViewModels;
using System.Collections.Generic;
using System.Net.Http;
namespace MyCompany.Tests.StaffPortal.ServiceA
{
public class ExtensionsControllerTests : TestBase
{
public ExtensionsControllerTests(CustomWebApplicationFactory<Startup> factory) : base(factory)
{
}
[Fact]
public async Task Test_GetExtensions()
{
//This line creates a new "web browser" and uses the login details provided to obtain and set up the token so that we can request information about an account.
HttpClient httpClient = await CreateAuthenticatedHttpClient("abcltd1@MyCompany.com", "test", 1);
//Perform any work and get the information from the API
//Contact the API using the token so check that it works
var getExtensionsResponse = await httpClient.GetAsync("/api/ServiceA/extensions/GetExtensions");
//Check that the response was OK
Assert.True(getExtensionsResponse.StatusCode == System.Net.HttpStatusCode.OK, "GetExtensions did not return an OK result.");
//Get and Convert the Content we received into a List of ServiceAExtensionViewModel, as that is what GetExtensions sends back to the browser.
var getExtensionsResponseContent = await getExtensionsResponse.Content.ReadAsStringAsync();
List<ServiceAExtensionViewModel> extensionList = JsonConvert.DeserializeObject<List<ServiceAExtensionViewModel>>(getExtensionsResponseContent);
//Check the information received matches our expectations
Assert.True(extensionList.Count == 2);
Assert.True(extensionList[0].PropertyA == 123);
Assert.True(extensionList[0].PropertyB == 0161);
Assert.True(extensionList[0].PropertyC == true);
}
}
}
这里是 CreateAuthenticatedHttpClient() 的内容供参考。
protected async Task<HttpClient> CreateAuthenticatedHttpClient(string username, string password, int companyAccountId)
{
var httpClient = _factory.CreateClient(
new WebApplicationFactoryClientOptions
{
AllowAutoRedirect = false
});
//Create the Login information to send to the server
var loginInformation = new LoginRequestModel
{
Username = username,
Password = password,
ReturnUrl = ""
};
//Convert it into Json which the server will understand
var validLoginRequestJson = ConvertToJson(loginInformation);
//Send the Json Login information to the server, and put the response we receive into loginResponse
//In the code below, httpClient is like a web browser. You give it the
var loginResponse = await httpClient.PostAsync("/api/authenticate", validLoginRequestJson);
//Check the loginResponse was a CREATED response, which means that the token was made
Assert.True(loginResponse.StatusCode == System.Net.HttpStatusCode.Created, "New Token was not returned.");
//Check the response is identified as being in Json format
Assert.Equal("application/json; charset=utf-8", loginResponse.Content.Headers.ContentType.ToString());
//Next we have to convert the received Json information into whatever we are expecting.
//In this case, we are expecting a AuthenticationResponseViewModel (because that's what the API sends back to the person trying to log in)
//First we get hold of the Content (which is in Json format)
var responseJsonString = await loginResponse.Content.ReadAsStringAsync();
//Second we convert the Json back into a real AuthenticationResponseViewModel
AuthenticationResponseViewModel authenticationResponseViewModel = JsonConvert.DeserializeObject<AuthenticationResponseViewModel>(responseJsonString);
//Now we take the Token from AuthenticationResponseViewModel, and add it into the httpClient so that we can check the Token works.
httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", authenticationResponseViewModel.token);
httpClient.DefaultRequestHeaders.Add("CompanyId", companyAccountId.ToString());
return httpClient;
}
解决方案
推荐阅读
- php - phpseclib TripleDES ECB 问题
- mysql - 根据条件组(或类似的东西)重置的逐行移动平均值
- android - 如何在 ExoPlayer android 中跳过部分视频
- oracle - 表格形式的 Oracle APEX 级联选择列表
- python - Django 模型:如何在视图函数中检索自定义错误消息?
- html - SSL 卸载 - 字体真棒图标问题
- c# - 反射:FindMembers 返回空
- ios - 在 UITableViewCell 内,我得到旧 UIWebView 的委托回调?
- c# - 如何获取 DataAnnotations.Compare 来比较 2 个不同对象的属性?
- apache-spark - 将数据帧内的数据字段从任何格式转换为 Spark Scala 中的固定格式