How to test an MVC controller with instantiation and action invocation from request content?

前端 未结 2 1355
滥情空心
滥情空心 2021-01-27 03:14

I have test-driven a Backbone model in Javascript, so I\'m sure that when user clicks the \"Save\" button, a proper POST request is being sent to my ASP.NET MVC application. Thi

相关标签:
2条回答
  • 2021-01-27 03:56

    jtabuloc has correctly pointed out that this is definitely an integration test issue. The requirement about having ASP.NET MVC stack running, and at the same time have an internal WebService stubbed is very hard to achieve, even if assuming that has some sense.

    From what I've learned, the only option to provide an encapsulated environment (i.e. no dedicated server) for integration testing a Web Application is to use either OWIN or ASP.NET Core. Currently, none of these are viable for me, as require upgrading MVC 4 and MVC 5 applications.

    Therefore this doesn't seem to be worth the cost currently - I'll stick to integration testing for WebService with a database, and unit-testing controllers and views.

    0 讨论(0)
  • 2021-01-27 04:00

    This sounds an integration test to me. Anyways, forget RhinoMock in this case because there's no other way to do it but to create your own test suite here. In our case we actually used HttpClient to call the controller/api and pass the url and argument needed for action and anticipate the result for validation.

    public class ClientHandler
    {
       private HttpClient _client;
    
       public ClientHander()
       {
            // add handler if needed ex var handler = new HttpClientHandler()
    
            _client = new HttpClient(/*handler*/);
    
            // add default header if needed client.DefaultRequestHeaders
       }
    
       public HttpResponseMessage Post(string path, HttpContent content)
       {
          // You can async if you want
          return _client.Post(path, content).Result;
       }
    }
    

    Now you can use it in your actual testing.

    [TestClass]
    public class MyController
    {
        [TestMethod]
        public void TestMyControllerActionSaveData()
        {  
             var client = new ClientHandler();
             var content = new StringContent(dataHere, Encoding.UTF8, "application/json");
             var outPut = client.Post("http://server/action/here", content).Result;
    
             // validate expected output here
        }
    }
    

    There are a lot of missing configuration and setup here but the gist is there.

    Update : I really like what you are currently doing in the name of testing because this is a powerful tool as part of Continues Integration (CI). Just a minor comment the way to name your test method. I would suggest to rename the test method into an action you want to do and put those procedure inside the test like what Gherkin way of BDD or as described by Dan North .

    [TestMethod]
    public void Should_Save_If_Has_Data()
    {
       Given(Web_Service_Instance)
         With(Data_To_Pass)
         When(Posting_Data_To_Service)
         Then(Data_Will_Be_Saved)
         Verify()
    }
    
    [TestMethod]
    public void Should_Not_Save_If_No_Data()
    {
        .....
    }
    

    If you can create a TestSuite like described above it will give you a lot of benefits in the long run and avoid repetition of code (DRY). Also those tests will serve as living documents as described by Robert C. Martin & Micah Martin. Special thanks to the team that Im involved and kudos is for them!

    0 讨论(0)
提交回复
热议问题