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

¿Fue útil?

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
scroll top