Witam. Piszę sobie testy integracyjne. Dokładnie testy logowania z wykorzystaniem OpenIdict. Mam metodę w testach Oznaczoną jako [Theory] oraz 2x InlineData.
Problem jest taki, że przy jednym teście (tym który uruchamia się drugi) OpenIdict mnie nie wpuszcza (mam komunikat, że zły client_id). Jeśli jeden z testów wyrzucę nie ważne który to działa.
Do uruchomienia servera testowego wykorzystuje to co pokazuje MS https://docs.microsoft.com/pl-pl/aspnet/core/test/integration-tests?view=aspnetcore-2.2
[Theory]
[InlineData("linkedin", "SomeInvalidLinkedInCode", "App", ApiErrorCode.LinkedInLoginError, HttpStatusCode.BadRequest)] //
[InlineData("linkedin", "SomeValidLinkedInCode", "App", ApiErrorCode.AccountNotActiveError, HttpStatusCode.BadRequest)] //To działa (uruchamia się pierwsz)
public async Task Call_LoginViaLinkedIn_Should_Return_CustomError(string grant_type, string code, string client, ApiErrorCode errorCode, HttpStatusCode statusCode)
{
_factory.DatabaseName = Guid.NewGuid().ToString();
HttpClient _fakeClient;
Mock<FakeHttpMessageHandler> _fakeHttpMessageHandler = new Mock<FakeHttpMessageHandler> { CallBase = true };
_fakeClient = new HttpClient(_fakeHttpMessageHandler.Object);
_fakeHttpMessageHandler.Setup(f => f.Send(It.IsAny<HttpRequestMessage>())).Returns((HttpRequestMessage message) =>
{
HttpContent content = null;
HttpStatusCode responseCode = HttpStatusCode.OK;
if (message.RequestUri.AbsoluteUri.Contains("accessToken", System.StringComparison.OrdinalIgnoreCase))
{
var messageContent=message.Content.ReadAsFormDataAsync().Result;
if (messageContent.Get(3) == "SomeValidLinkedInCode")
{
content = new StringContent(System.IO.File.ReadAllText("LinkedInAuth.json"));
responseCode = HttpStatusCode.OK;
}
else
{
responseCode = HttpStatusCode.BadRequest;
}
}
if (message.RequestUri.AbsoluteUri.Contains("me?projection=", System.StringComparison.OrdinalIgnoreCase))
{
responseCode = HttpStatusCode.OK;
content = new StringContent(System.IO.File.ReadAllText("LinkedInProfile.json"));
}
if (message.RequestUri.AbsoluteUri.Contains("v2/emailAddress?", System.StringComparison.OrdinalIgnoreCase))
{
responseCode = HttpStatusCode.OK;
content = new StringContent(System.IO.File.ReadAllText("LinkedInEmail.json"));
}
if (message.RequestUri.AbsoluteUri.Contains("image"))
{
responseCode = HttpStatusCode.OK;
content = new StringContent("someImageBytes");
}
return new HttpResponseMessage
{
StatusCode = responseCode,
Content = content
};
});
var testClient = _factory.WithWebHostBuilder(builder =>
{
builder.ConfigureTestServices(services =>
{
services.Remove(new ServiceDescriptor(typeof(HttpClient), ServiceLifetime.Scoped));
services.AddScoped<HttpClient>(x => _fakeClient);
});
}).CreateClient(new WebApplicationFactoryClientOptions
{
AllowAutoRedirect = false
});
var parameters = GetParameters(grant_type, code, client);
var httpRequest = new HttpRequestMessage(HttpMethod.Post, "/connect/token")
{
Content = new FormUrlEncodedContent(parameters)
};
var httpResponse = await testClient.SendAsync(httpRequest);
var value = await httpResponse.Content.ReadAsStringAsync();
var response = JsonConvert.DeserializeObject<CustomErrorResponse>(value);
Assert.Equal(statusCode, httpResponse.StatusCode);
Assert.Equal(errorCode, response.ErrorCode);
}
Gdy zakomentuję jeden inline to działa.
Oczywiście aplikacje, które mogę uderzać do OpenIdConnectRequest są dodawane w klasie Startup zgodnie z tym co w dokumentacji OpenId.