ASP.NET Web API アプリケーションのルートをテストする最良の方法は、エンドポイントの統合テストです。
ASP.NET Web API アプリケーションの簡単な統合テスト サンプルを次に示します。これは主にルートをテストするわけではありませんが、目に見えない形でテストします。また、ここでは XUnit、Autofac、および Moq を使用しています。
[Fact, NullCurrentPrincipal]
public async Task
Returns_200_And_Role_With_Key() {
// Arrange
Guid key1 = Guid.NewGuid(),
key2 = Guid.NewGuid(),
key3 = Guid.NewGuid(),
key4 = Guid.NewGuid();
var mockMemSrv = ServicesMockHelper
.GetInitialMembershipService();
mockMemSrv.Setup(ms => ms.GetRole(
It.Is<Guid>(k =>
k == key1 || k == key2 ||
k == key3 || k == key4
)
)
).Returns<Guid>(key => new Role {
Key = key, Name = "FooBar"
});
var config = IntegrationTestHelper
.GetInitialIntegrationTestConfig(GetInitialServices(mockMemSrv.Object));
using (var httpServer = new HttpServer(config))
using (var client = httpServer.ToHttpClient()) {
var request = HttpRequestMessageHelper
.ConstructRequest(
httpMethod: HttpMethod.Get,
uri: string.Format(
"https://localhost/{0}/{1}",
"api/roles",
key2.ToString()),
mediaType: "application/json",
username: Constants.ValidAdminUserName,
password: Constants.ValidAdminPassword);
// Act
var response = await client.SendAsync(request);
var role = await response.Content.ReadAsAsync<RoleDto>();
// Assert
Assert.Equal(key2, role.Key);
Assert.Equal("FooBar", role.Name);
}
}
このテストに使用する外部ヘルパーがいくつかあります。それらの 1 つは、NullCurrentPrincipalAttribute
です。テストは Windows ID で実行Thread.CurrentPrincipal
されるため、 はこの ID で設定されます。したがって、アプリケーションである種の承認を使用している場合は、最初にこれを取り除くのが最善です。
public class NullCurrentPrincipalAttribute : BeforeAfterTestAttribute {
public override void Before(MethodInfo methodUnderTest) {
Thread.CurrentPrincipal = null;
}
}
次に、モックを作成しますMembershipService
。これはアプリケーション固有のセットアップです。したがって、これは独自の実装に合わせて変更されます。
はGetInitialServices
Autofac コンテナーを作成します。
private static IContainer GetInitialServices(
IMembershipService memSrv) {
var builder = IntegrationTestHelper
.GetEmptyContainerBuilder();
builder.Register(c => memSrv)
.As<IMembershipService>()
.InstancePerApiRequest();
return builder.Build();
}
GetInitialIntegrationTestConfig
メソッドは、構成を初期化するだけです。
internal static class IntegrationTestHelper {
internal static HttpConfiguration GetInitialIntegrationTestConfig() {
var config = new HttpConfiguration();
RouteConfig.RegisterRoutes(config.Routes);
WebAPIConfig.Configure(config);
return config;
}
internal static HttpConfiguration GetInitialIntegrationTestConfig(IContainer container) {
var config = GetInitialIntegrationTestConfig();
AutofacWebAPI.Initialize(config, container);
return config;
}
}
メソッドはRouteConfig.RegisterRoutes
基本的にルートを登録します。HttpClient
を作成するための小さな拡張メソッドもありますHttpServer
。
internal static class HttpServerExtensions {
internal static HttpClient ToHttpClient(
this HttpServer httpServer) {
return new HttpClient(httpServer);
}
}
最後に、新しいインスタンスHttpRequestMessageHelper
を構築するための静的メソッドの束を持つ静的クラスを呼び出します。HttpRequestMessage
internal static class HttpRequestMessageHelper {
internal static HttpRequestMessage ConstructRequest(
HttpMethod httpMethod, string uri) {
return new HttpRequestMessage(httpMethod, uri);
}
internal static HttpRequestMessage ConstructRequest(
HttpMethod httpMethod, string uri, string mediaType) {
return ConstructRequest(
httpMethod,
uri,
new MediaTypeWithQualityHeaderValue(mediaType));
}
internal static HttpRequestMessage ConstructRequest(
HttpMethod httpMethod, string uri,
IEnumerable<string> mediaTypes) {
return ConstructRequest(
httpMethod,
uri,
mediaTypes.ToMediaTypeWithQualityHeaderValues());
}
internal static HttpRequestMessage ConstructRequest(
HttpMethod httpMethod, string uri, string mediaType,
string username, string password) {
return ConstructRequest(
httpMethod, uri, new[] { mediaType }, username, password);
}
internal static HttpRequestMessage ConstructRequest(
HttpMethod httpMethod, string uri,
IEnumerable<string> mediaTypes,
string username, string password) {
var request = ConstructRequest(httpMethod, uri, mediaTypes);
request.Headers.Authorization = new AuthenticationHeaderValue(
"Basic",
EncodeToBase64(
string.Format("{0}:{1}", username, password)));
return request;
}
// Private helpers
private static HttpRequestMessage ConstructRequest(
HttpMethod httpMethod, string uri,
MediaTypeWithQualityHeaderValue mediaType) {
return ConstructRequest(
httpMethod,
uri,
new[] { mediaType });
}
private static HttpRequestMessage ConstructRequest(
HttpMethod httpMethod, string uri,
IEnumerable<MediaTypeWithQualityHeaderValue> mediaTypes) {
var request = ConstructRequest(httpMethod, uri);
request.Headers.Accept.AddTo(mediaTypes);
return request;
}
private static string EncodeToBase64(string value) {
byte[] toEncodeAsBytes = Encoding.UTF8.GetBytes(value);
return Convert.ToBase64String(toEncodeAsBytes);
}
}
アプリケーションで基本認証を使用しています。したがって、このクラスにはHttpRequestMessege
、Authentication ヘッダーを使用して を構築するメソッドがいくつかあります。
最後に、ActとAssertを実行して、必要なものを検証します。これはやり過ぎのサンプルかもしれませんが、これで素晴らしいアイデアが得られると思います。
これは、 HttpServer を使用した統合テストに関するすばらしいブログ投稿です。また、 ASP.NET Web API でのルートのテストに関する別の素晴らしい投稿もあります。