IHttpActionResult and Integration Testing Web API v2 Put in MS Test
asp.net-web-api, c#, integration-testing, mstest
Solution
Considering your comment about in-memory database change you are planning for, following are some examples of how you could do write tests in your scenario:
PeopleController people = new PeopleController();
// mismatched person Id returns BadRequest
Person person = new Person();
person.Id = 11;
person.Name = "John updated";
IHttpActionResult result = people.PutPerson(10, person).Result;
Assert.IsInstanceOfType(result, typeof(BadRequestResult));
// ---------------------------------------------------
// non-existing person
Person person = new Person();
person.Id = 1000;
person.Name = "John updated";
IHttpActionResult result = people.PutPerson(1000, person).Result;
Assert.IsInstanceOfType(result, typeof(NotFoundResult));
// --------------------------------------------------------
//successful update of person information and its verification
Person person = new Person();
person.Id = 10;
person.Name = "John updated";
IHttpActionResult result = people.PutPerson(10, person).Result;
StatusCodeResult statusCodeResult = result as StatusCodeResult;
Assert.IsNotNull(statusCodeResult);
Assert.AreEqual<HttpStatusCode>(HttpStatusCode.NoContent, statusCodeResult.StatusCode);
//retrieve the person to see if the update happened successfully
IHttpActionResult getPersonResult = people.GetPerson(10).Result;
OkNegotiatedContentResult<Person> negotiatedResult = getPersonResult as OkNegotiatedContentResult<Person>;
Assert.IsNotNull(negotiatedResult);
Assert.AreEqual<string>(person.Name, negotiatedResult.Content.Name);
Problem
VS2013 auto generated a web api v2 controller for me based on my EF context. I am trying to unit test the put part of the controller. No matter what i do i can't get my asserts to check the StatusCodeResult return. The auto generated code looks like this: ``` // PUT api/Vendor/5 public IHttpActionResult PutVendor(int id, Vendor vendor) { if (!ModelState.IsValid) { return BadRequest(ModelState); } if (id != vendor.Id) { return BadRequest(); } db.Entry(vendor).State = EntityState.Modified; try { db.SaveChanges(); } catch (DbUpdateConcurrencyException) { if (!VendorExists(id)) { return NotFound(); } else { throw; } } return StatusCode(HttpStatusCode.NoContent); } ``` My Integration test looks like this: ``` [TestMethod] public void PutVendor_UpdateVendorRecord_ReturnsTrue() { // Arrange //CleanUpVendors(); var controller = new VendorController(ctx); const string vendorName = "Unit Test Company"; // Add vendor to database ctx.Vendors.Add(new Vendor { Active = true, Name = vendorName }); ctx.SaveChanges(); var myVendor = (from v in ctx.Vendors where v.Name == vendorName select v).FirstOrDefault(); // Get Newly Inserted ID Assert.IsNotNull(myVendor, "Vendor is Null"); myVendor.Name = "New Name"; // Act var httpActionResult = controller.PutVendor(myVendor.Id, myVendor); //var response = httpActionResult as OkNegotiatedContentResult<Vendor>; var response = httpActionResult as OkNegotiatedContentResult<Vendor>; // Assert } ``` Is there something wrong with my test? What should my Asserts look like? This assert returns true: ``` Assert.IsInstanceOfType(httpActionResult, typeof(System.Web.Http.Results.StatusCodeResult)); ``` but I don't think it is actually testing anything except that there was some kind of return. Any help would be greatly appreciated.