Pruebas de controlador MVC Acción HttpAcceptAttribute Verbos
-
21-09-2019 - |
Pregunta
¿Cuál es la mejor manera de probar la unidad la acción del controlador HttpAcceptAttribute verbos?
Hasta ahora tengo el siguiente pero es tan feo incluso una madre no podía amarlo y no muy flexible. ¿Hay una mejor manera?
[Fact] // using xUnit, mocking controller in class
public void FilterControllerTestRemoveFilterByProductAttributeIsOfTypePost()
{
Type[] paramTypes = new[] { typeof(int) };
var method = typeof(FilterController).GetMethod("MyMethod", paramTypes);
var attributes = method.GetCustomAttributes(typeof(AcceptVerbsAttribute), false).Cast<AcceptVerbsAttribute>().SingleOrDefault();
Assert.NotNull(attributes);
Assert.Equal(1, attributes.Verbs.Count());
Assert.True(attributes.Verbs.First().Equals(HttpVerbs.Post.ToString(), StringComparison.InvariantCultureIgnoreCase));
}
Gracias Mac
Solución
No hay reflexión y mágicas cuerdas, fácil de cambiar el nombre del controlador y el método sin romper la unidad de prueba:
[TestMethod]
public void HomeController_Index_Action_Should_Accept_Post_Verb_Only()
{
Expression<Action<HomeController>> expression = (HomeController c) => c.Index(null);
var methodCall = expression.Body as MethodCallExpression;
var acceptVerbs = (AcceptVerbsAttribute[])methodCall.Method.GetCustomAttributes(typeof(AcceptVerbsAttribute), false);
acceptVerbs.ShouldNotBeNull("");
acceptVerbs.Length.ShouldBe(1);
acceptVerbs[0].Verbs.First().ShouldBe("POST");
}
Otros consejos
using System;
using System.Linq;
using System.Reflection;
using System.Web.Mvc;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Unknown.Tests
{
public static class MvcAssert
{
public static MemberInfo[] HasPostAction(Controller controller, string actionName, int expectedCount)
{
if (controller == null)
throw new ArgumentNullException("controller");
if (string.IsNullOrEmpty(actionName))
throw new ArgumentNullException("actionName");
MemberInfo[] members = controller.GetType().FindMembers(
MemberTypes.Method,
BindingFlags.Public | BindingFlags.Instance,
(m, c) => (m.Name == actionName && m.IsDefined(typeof(AcceptVerbsAttribute), false) && ((AcceptVerbsAttribute)Attribute.GetCustomAttribute(m, typeof(AcceptVerbsAttribute))).Verbs.Any((v) => v.Equals("Post", StringComparison.InvariantCultureIgnoreCase))),
null);
Assert.AreEqual<int>(expectedCount, members.Length);
return members;
}
}
}
Uso
public void FilterControllerTestRemoveFilterByProductAttributeIsOfTypePost()
{
FilterController controller = new FilterController();
MvcAssert.HasPostAction(controller, "RemoveFilterByProduct", 1);
}
using System;
using System.Linq;
using System.Reflection;
using System.Web.Mvc;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace MvcApplication4.Tests
{
public static class MvcAssert
{
public static MethodInfo ActionExists(Controller controller, string actionName, HttpVerbs expectedVerbs, params Type[] paramTypes)
{
if (controller == null)
throw new ArgumentNullException("controller");
if (string.IsNullOrEmpty(actionName))
throw new ArgumentNullException("actionName");
int actualVerbs = 0;
MethodInfo action = controller.GetType().GetMethod(actionName, paramTypes);
Assert.IsNotNull(action, string.Format("The specified action '{0}' could not be found.", actionName));
AcceptVerbsAttribute acceptVerb = Attribute.GetCustomAttribute(action, typeof(AcceptVerbsAttribute)) as AcceptVerbsAttribute;
if (acceptVerb == null)
actualVerbs = (int)HttpVerbs.Get;
else
actualVerbs = (int)Enum.Parse(typeof(HttpVerbs), string.Join(", ", acceptVerb.Verbs.ToArray()), true);
Assert.AreEqual<int>(actualVerbs, (int)expectedVerbs);
return action;
}
}
}
versión
bit modificado Una solución Darin`s.
[Fact]
public void Delete_Verb(){
VerifyVerb<HttpDeleteAttribute>(x=>x.Delete(null));
}
protected void VerifyVerb<TVerbType>(Expression<Action<T>> exp){
var methodCall = exp.Body as MethodCallExpression;
var acceptVerbs = methodCall.Method
.GetCustomAttributes(typeof(TVerbType), false);
acceptVerbs.Should().Not.Be.Null();
acceptVerbs.Length.Should().Be(1);
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow