我正在尝试在.NET Core 2.0 API项目中测试ActionFilterAttribute,并想知道最好的方法。注意,我不是试图通过控制器动作测试它,只是测试ActionFilterAttribute本身。
我如何测试这个:
public class ValidateModelAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
if (!context.ModelState.IsValid)
{
context.Result = new BadRequestObjectResult(context.ModelState);
}
}
}
答案 0 :(得分:17)
创建上下文的实例将其传递给过滤器并断言预期的行为
例如
[TestClass]
public class ValidateModelAttributeTest {
[TestMethod]
public void Invalid_ModelState_Should_Return_BadRequestObjectResult() {
//Arrange
var httpContext = new DefaultHttpContext();
var context = new ActionExecutingContext(
new ActionContext
{
HttpContext = httpContext,
RouteData = new RouteData(),
ActionDescriptor = new ActionDescriptor(),
},
new List<IFilterMetadata>(),
new Dictionary<string, object>(),
new Mock<Controller>().Object);
var sut = new ValidateModelAttribute();
//Act
sut.OnActionExecuting(context);
//Assert
context.Result.Should().NotBeNull()
.And.BeOfType<BadRequestObjectResult>();
}
}
答案 1 :(得分:0)
这是一个真实的示例,在这里我还访问了动作过滤器属性内的方法信息和参数:
假设我有一个具有ActionAttribute的Controller方法,如下所示:
public class HomeController : Controller
{
...
[FeatureFlagActionAtrribute("user", new String[] { "Feature1" })]
public IActionResult DoSomethingWithFilterAction(String user)
{...}
}
http调用将如下所示:
/ Home / DoSomethingWithFilterAction?user =“ user1”
现在,我想在这样的上下文中测试ActionAttribute FeatureFlagActionAtrribute。
如果您将上述建议应用于该示例,则它看起来像这样(至少对我有用)
var methodInfoDoSomethingWithFilterAction = typeof(HomeController).GetMethod(nameof(HomeController.DoSomethingWithFilterAction));
var httpContext = new DefaultHttpContext();
var routeData = new RouteData();
FeatureFlagActionAtrribute FeatureFlagActionAtrributeFilter = methodInfoDoSomethingWithFilterAction.GetCustomAttribute<FeatureFlagActionAtrribute>();
ActionDescriptor actionDescriptor = new ControllerActionDescriptor()
{
ActionName = methodInfoDoSomethingWithFilterAction.Name,
ControllerName = typeof(FeatureFlagTest).Name,
DisplayName = methodInfoDoSomethingWithFilterAction.Name,
MethodInfo = methodInfoDoSomethingWithFilterAction,
};
ActionContext actionContext = new ActionContext(httpContext, routeData, actionDescriptor) ;
var homeController = new HomeController();
var attribute = new FeatureFlagActionAtrribute("user", new string[] { "feature1" });
IDictionary<string, object> actionArguments = new Dictionary<string, object>
{
["user"] = "user1"
};
var filterMetadata = new List<IFilterMetadata>() { featureFlagActionAtrributeFilter };
ActionExecutingContext actionExecutedContext = new
ActionExecutingContext(actionContext, filterMetadata, actionArguments, homeController);
attribute.OnActionExecuting(actionExecutedContext);
然后在ActionFilterAttribute内部:
public override void OnActionExecuting(ActionExecutingContext context)
{
ControllerActionDescriptor actionDescriptor = (ControllerActionDescriptor)context.ActionDescriptor;
Debug.Print($"2. @Before Method called {actionDescriptor.ControllerName}Controller.{actionDescriptor.ActionName}");
var controllerName = actionDescriptor.ControllerName;
var actionName = actionDescriptor.ActionName;
IDictionary<object, object> properties = actionDescriptor.Properties;
ParameterInfo[] paramsOfMethod = actionDescriptor.MethodInfo.GetParameters();
var fullName = actionDescriptor.DisplayName;
var paramNameForKeyOfFeature = ParamNameForKeyOfFeature;
var arguments = context.ActionArguments;