3

コントローラアクションのHttpAcceptAttribute動詞を単体テストするための最良の方法は何ですか?

今のところ私は以下を持っていますが、それはとても醜いです、母親でさえそれを愛することができず、あまり柔軟ではありません。もっと良い方法はありますか?

[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));
}

ありがとうMac

4

4 に答える 4

3

リフレクションと魔法の文字列がなく、単体テストを中断することなく、コントローラーとメソッドの名前を簡単に変更できます。

[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");
}
于 2009-10-18T16:46:49.803 に答える
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;
        }

    }

}
于 2009-10-18T16:44:26.313 に答える
1
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;
        }

    }

}

使用する

public void FilterControllerTestRemoveFilterByProductAttributeIsOfTypePost()
{
    FilterController controller = new FilterController();
    MvcAssert.HasPostAction(controller, "RemoveFilterByProduct", 1);
}
于 2009-10-18T06:26:40.390 に答える
0

少し修正されたバージョンのダーリンのソリューション。

  [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);
  }
于 2010-08-29T15:05:54.177 に答える