views:

424

answers:

1

Hi folks,

i've got the following Action Method I'm trying to moq test. Notice the AcceptVerbs? I need to make sure i'm testing that.

here's the method.

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([Bind(Include = "Subject, Content")]Post post,
    HttpPostedFileBase imageFileName)
{
  ...
}

here's the moq code i have...

[TestMethod]
public void Create_Action_snip_sniop_When_Http_Post_Is_Succesful()
{
    // Arrange.
    var mock = new Mock<ControllerContext>();
    mock.SetupGet(m => m.HttpContext.Request.HttpMethod).Returns("POST");

    // Snip some other arrangements.

    var controller = PostController;
    controller.ControllerContext = mock.Object;

    // Act.
    var viewResult = controller.Create(post, image.Object) as ViewResult;

    // Assert.
    Assert.IsNotNull(viewResult);

    // TODO: Test that the request was an Http-Post.

what do i need to do to verify the request was a post?

+5  A: 

Your attribute won't be invoked when running as a unit test because it is normally invoked by the ControllerActionInvoker as part of the Mvc "stack". What I've done in cases like this is to write a test to make sure that the correct attribute is applied to the action with the correct parameters. Then I trust that the framework will do its job correctly.

Doing this requires reflection:

 public void Only_posts_are_allowed_to_my_action()
 {
       var method = typeof(MyController).GetMethod("MyAction");
       var attribute = method.GetCustomAttributes(typeof(AcceptVerbsAttribute),false)
                             .Cast<AcceptVerbsAttribute>();
                             .SingleOrDefault();

       Assert.IsNotNull( attribute );
       Assert.AreEqual( 1, attributes.Count() );
       Assert.IsTrue( attributes.Contains( HttpVerbs.Post ) );
 }
tvanfosson
So what you're saying is that you're testing to make sure that you have decorated the specific controller method with the .Post verb .. as opposed to testing that the method was fired on a Request is Http-posted (because that's plumbing way outside of this scope -> it's framework stuff).. ?
Pure.Krome
Correct. The functionality that invokes the filter is outside the scope of the method (fired first before the method is invoked) so you'll never see a non-POST in your method if the correct attribute is applied.
tvanfosson