我正在使用 XUnit 和 WebApplicationFactory 为我的 C# API 应用程序编写集成测试
GetTokenControllerTest 将调用 GetToken() 将身份验证代码存储在 AccessToken 中,然后可以在整个类中使用该代码。使用授权设置标头值,允许我访问控制器中的授权端点
public class TokenDTO
{
public string AccessToken { get; set; }
}
public class GetTokenControllerTest : IClassFixture<TokenDTO>
{
private readonly HttpClient _client;
private readonly TokenDTO _tokenDTO;
public GetTokenControllerTest(TokenDTO tokenDTO)
{
_tokenDTO = tokenDTO;
var factory = new WebApplicationFactory<Program>();
_client = factory.CreateClient();
}
[Fact, TestPriority(1)]
public async Task GetToken()
{
TokenRequestDto dto = new TokenRequestDto();
dto.Email = "[email protected]";
dto.Password = "123456";
var payload = JsonConvert.SerializeObject(dto);
var content = new StringContent(payload, Encoding.UTF8, "application/json");
var GetTokenContentsResponse = await _client.PostAsync("/api/Tokens/Auth", content);
var TokenJson = GetTokenContentsResponse.Content.ReadAsStringAsync().Result;
var TokenDTO = JsonConvert.DeserializeObject<TokenDto>(TokenJson);
//Set token so can use through out class
_tokenDTO.AccessToken = TokenDTO.AccessToken;
}
[Fact]
public async Task CallAPIEndPoint1()
{
//re-use AccessToken
_client.DefaultRequestHeaders.Add("Authorization", "Bearer " + _tokenDTO.AccessToken);
var api1 = await _client.GetAsync("api/Car/CarNames");
}
[Fact]
public async Task CallAPIEndPoint2()
{
//re-use AccessToken
_client.DefaultRequestHeaders.Add("Authorization", "Bearer " + _tokenDTO.AccessToken);
var api2 = await _client.GetAsync("api/Car/CarTypes");
}
[Fact]
public async Task CallAPIEndPoint2()
{
//re-use AccessToken
_client.DefaultRequestHeaders.Add("Authorization", "Bearer " + _tokenDTO.AccessToken);
var api3 = await _client.GetAsync("api/Car/CarColour");
}
}
这样我就可以成功调用控制器函数了:
[Authorize]
[HttpPost("CarNames")
public async Task<IActionResult> CarNames()
{
try
{
//do something
}
catch (Exception ex)
{
}
}
这一切都很好,我的问题是如何将 TokenDTO.AccessToken 设置为全局变量,该变量可以在测试期间跨所有测试类访问?
感谢您的回复
使用
IClassFixture
,您就朝着正确的方向迈出了一步。以下是如何创建 Fixture 类来获取令牌的示例。
public class TokenFixture { public TokenFixture() { Token = GetToken().Result; } private async Task<string> GetToken() { // replace with actual token requesting logic var token = await Task.FromResult("Token"); return token; } public string Token { get; set; } }
然后你就可以在你的
GetTokenControllerTest.cs
中使用它:
public class ControllerTests: IClassFixture<TokenFixture>
{
TokenFixture fixture;
public ControllerTests(TokenFixture fixture)
{
this.fixture = fixture;
}
[Fact]
public void Test1()
{
Assert.Equal("Token", fixture.Token);
}
[Fact]
public void Test2()
{
Assert.Equal("Token", fixture.Token);
}
}