asp.net-mvc - 使用 Asp.Net Web Api 和客户过滤器进行单元测试
问题描述
我正在研究 Asp.Net Mvc Web Api 中的单元测试。我有 2 个项目
1:Catalog.Api - 这包含所有控制器
2:Catalog.UnitTests - 这包含控制器的单元测试
所有控制器都通过“ApiController”继承,每个控制器都有自定义过滤器 [AuthenticationFilter]。这是我的价值观控制器。
[AuthenticationFilter]
public class ValuesController : ApiController
{
// GET api/values
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/values/5
public string Get(int id)
{
return "value";
}
// POST api/values
public void Post([FromBody]string value)
{
}
// PUT api/values/5
public void Put(int id, [FromBody]string value)
{
}
// DELETE api/values/5
public void Delete(int id)
{
}
}
我的习惯是检查授权令牌。这里是
public class AuthenticationFilter: AuthorizationFilterAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
var request = actionContext.Request;
var authorization = request.Headers.Authorization;
if (authorization == null || authorization.Scheme != "Bearer")
{
ShowAuthenticationError(actionContext, "Authorization required");
return;
}
if (string.IsNullOrEmpty(authorization.Parameter))
{
ShowAuthenticationError(actionContext, "Missing Jwt Token");
return;
}
var token = authorization.Parameter;
var principal = AuthenticateToken(token);
if (principal == null)
{
ShowAuthenticationError(actionContext, "Invalid token");
return;
}
base.OnAuthorization(actionContext);
}
private static void ShowAuthenticationError(HttpActionContext filterContext, string message)
{
var responseDTO = new ResponseDTO() { Code = 401, Message = message };
filterContext.Response =
filterContext.Request.CreateResponse(HttpStatusCode.Unauthorized, responseDTO);
}
}
public class ResponseDTO
{
public int Code { get; set; }
public string Message { get; set; }
}
现在在单元测试项目中,我有一个类和单元测试方法。
[TestMethod]
public void CheckFilter()
{
try
{
var controller = new ValuesController();
var controllerContext = new HttpControllerContext();
var request = new HttpRequestMessage();
request.Headers.Add("Authorization", "bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6InVhbGkiLCJlbWFpbCI6InVhbGlAaW5yZWFjaGNlLmNvbSIsIm5iZiI6MTU2NDY0NjIyMSwiZXhwI");
controllerContext.Request = request;
controller.ControllerContext = controllerContext;
var result = controller.Get();
Assert.IsTrue(result.Any());
}
catch (Exception ex)
{
Assert.Fail();
}
}
我通过将 API 项目的引用添加到我的单元测试项目中来调用我的控制器。所以所有的控制器都可以在单元测试项目中使用。
问题是当我调用值控制器时,它总是返回数据。当我删除请求和标头时,它也会返回数据,但在这种情况下,这将是未经授权的。
我认为我的自定义过滤器没有调用。应该如何调用并验证用户。
解决方案
我检查了您的问题并配置了该问题,基本上您是直接调用控制器。基本上控制器是一个类,当您调用它时,它的行为就像一个简单的类并调用方法并发回结果。简单明了
但是在你的情况下,你有你的 api 项目,所以可以这样做。
[TestMethod]
public void CheckFilter()
{
try
{
var config = new HttpConfiguration();
// This is the resgister method which is written in you Api project. That code is after this method this method because i did the same thing to call my controller.
Catalog.Api.WebApiConfig.Register(config);
using (var server = new HttpServer(config))
{
var client = new HttpClient(server);
string url = "http://localhost:PortNumberOfProject/api/values";
var request = new HttpRequestMessage
{
RequestUri = new Uri(url),
Method = HttpMethod.Get
};
request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "Your Token");
var response = await client.SendAsync(request);
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
}
catch (Exception ex)
{
Assert.Fail();
}
}
这是Api项目的WebApi Register方法,用于注册Api和Routes。
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
这是您的控制器。现在调试您的测试并在您的 [AuthenticationFilter] 和 OnAuthorization 方法中添加一个断点。
[AuthenticationFilter]
public class ValuesController : ApiController
{
// GET api/values
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
}
推荐阅读
- git - GitHub/GitLab REST API - 将分支直接合并到 Master
- c# - 在 c++ 中调用 c# 可执行文件托管并异步运行
- excel - EXCEL - 当数据透视图没有行字段时数据透视图时间序列
- gem5 - 问题是关于运行基准和老化 gem5
- tensorflow - 在 cpu 而不是 gpu 上使用带有 nvidia tensorrt 的 .h5 模型
- vb.net - 动态获取控件的名称和属性
- hyperledger-fabric - 本地运行 Fabric CA - 找不到默认的“PKCS11”BCCSP
- node.js - 如何在 Node.js 中将公钥创建为二进制可分辨编码规则 (DER) 编码的对象?
- c++ - 使用 SOIL_load_OGL_texture 加载纹理时出错
- python - 没有名为 Zeep 的模块 - Python