我有ApiController
并希望使用包括路由在内的单元测试进行测试。
一个例子:
[RoutePrefix("prefix")]
public class Controller : ApiController
{
[HttpGet]
[Route("{id1}")]
public int Add(int id1, [FromUri] int id2)
{
return id1 + id2;
}
}
我现在想测试一下这个方法。我明白了,我可以像普通方法一样测试它。但我还想通过将URL转换为方法参数来测试它。
基本上我想进行一次自动测试,我调用像prefix/10?id2=5
这样的网址,得到15的结果。这有可能吗?
答案 0 :(得分:3)
我为内存中集成测试编写了一个小助手类,可以作为测试套件的一部分进行调用。
internal interface IHttpTestServer : IDisposable {
HttpConfiguration Configuration { get; }
HttpClient CreateClient();
}
internal class HttpTestServer : IHttpTestServer {
HttpServer httpServer;
public HttpTestServer(HttpConfiguration configuration = null) {
httpServer = new HttpServer(configuration ?? new HttpConfiguration());
}
public HttpConfiguration Configuration {
get { return httpServer.Configuration; }
}
public HttpClient CreateClient() {
var client = new HttpClient(httpServer);
return client;
}
public void Dispose() {
if (httpServer != null) {
httpServer.Dispose();
httpServer = null;
}
}
public static IHttpTestServer Create(HttpConfiguration configuration = null) {
return new HttpTestServer(configuration);
}
}
然后会像这样使用它
[TestMethod]
public async Task HttpClient_Should_Get_OKStatus_From_InMemory_Hosting() {
using (var server = new HttpTestServer()) {
MyWebAPiProjectNamespace.WebApiConfig.Configure(server.Configuration);
var client = server.CreateClient();
string url = "http://localhost/prefix/10?id2=5";
var expected = 15;
var request = new HttpRequestMessage {
RequestUri = new Uri(url),
Method = HttpMethod.Get
};
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
using (var response = await client.SendAsync(request)) {
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
var result = await response.Content.ReadAsAsync<int>();
Assert.AreEqual(expected, result);
}
}
}
这将配置一个内存测试服务器,测试可以使用其httpclient进行调用。它本质上是一个端到端的集成测试。
答案 1 :(得分:2)
使用Microsoft ASP.NET Web API 2.2 OWIN包创建OWIN StartUp类:
public class Startup
{
public void Configuration(IAppBuilder builder)
{
var config = new HttpConfiguration();
builder.UseWebApi(config);
config.MapHttpAttributeRoutes();
config.EnsureInitialized();
}
}
在测试中使用Microsoft ASP.NET Web API 2.2 Self Host软件包(例如,使用NUnit):
[Test]
[TestCase(10, 5, 15)]
[TestCase(1, 2, 3)]
// add your test cases
public async Task AdditionTests(int a, int b, int result)
{
// Arrange
var address = "http://localhost:5050";
using (WebApp.Start<Startup>(address))
{
var client = new HttpClient();
var requestUri = $"{address}/prefix/{a}?id2={b}";
// Act
var response = await client.GetAsync(requestUri);
// Assert
Assert.IsTrue(await response.Content.ReadAsAsync<int>() == result);
}
}
答案 2 :(得分:1)
可以通过使用邮递员或提琴手来测试url param ..
答案 3 :(得分:1)
这是一个集成测试,而不是单元测试。如果你想自动执行此操作,你必须拥有一个工具来启动/托管你的web api,然后对它执行请求。
如果你想将它作为单元测试保留,虽然你可以验证类和方法的属性并检查值。
var type = typeof(Controller);
var attributeRoutePrefix = type.GetCustomAttribute(typeof(RoutePrefixAttribute)) as RoutePrefixAttribute;
Assert.IsNotNull(attributeRoutePrefix);
Assert.AreEqual("prefix", attributeRoutePrefix.Prefix);
var methodAttribute = type.GetMethod(nameof(Controller.Add)).GetCustomAttribute(typeof(RouteAttribute)) as RouteAttribute;
Assert.IsNotNull(methodAttribute);
Assert.AreEqual("id1", methodAttribute.Template);