1 / 40

Web Service Testing

Web Service Testing. Unit Testing. Doncho Minkov. Telerik Software Academy. http://academy.telerik.com. Senior Technical Trainer. http://minkov.it. Table of Contents. Ways of web service testing Unit Testing Integration Testing Complete Testing of Web Services

sona
Download Presentation

Web Service Testing

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Web Service Testing Unit Testing Doncho Minkov Telerik Software Academy http://academy.telerik.com Senior Technical Trainer http://minkov.it

  2. Table of Contents • Ways of web service testing • Unit Testing • Integration Testing • Complete Testing of Web Services • Unit testing the data layer • Unit testing the repositories layer • Unit testing the controllers • Integration testing the web services

  3. Web Service Testing

  4. Web Service Testing • Web service unit testing is much like regular unit testing • Writing test methods to test methods etc.. • Yet a service is build from many more components than POCO objects • There are the objects, service routing, media types, HTTP Status codes, etc…

  5. Web Service Testing (2) • When a web service is ready for test, the testing itself is performed in the following steps: • Write Unit Tests to test the C# objects • Test all objects, their constructors, their methods • Write the Integration Testing • Test the application as if a user tests it

  6. Unit Testing Testing the Work of the Controllers

  7. Unit Testing • The core idea of Unit testing is to test small components of an application • Test a single behavior (a method, property, constructor, etc…) • Unit tests cover all C# components of the app • Models and data layer • Like repositories and DB/XML read/write • Business layer • Controllers and their actions

  8. Unit Testing the Data Layer

  9. Unit Testing the Data Layer • The data layer is the one thing that most of the time does not need testing • The idea of the data layer is to reference a data storewith a ready-to-use framework • EntityFramework, NHibernate, OpenAccess • They are already tested enough • No point of testing dbContext.Set<T>.Add(), right?

  10. Unit Testing the Repositories

  11. Unit Testing the Repositories • It is essential to test the implementations of our repositories • The repositories contain the data store logic • All custom (developer) logic must be tested • A missing dbContext.SaveChanges() can cause a lot of pain

  12. Unit Testing the Repositories (2) • How to test the data store logic? • Writing and deleting the original (production) database is not quite a good option • Imagine a failed test that leaves 100ktest records in the database

  13. Ways to Unit Test a Data Store • A few ways exist to unit test a data store • Manually create a copy of the data store and work on the copy • Backup the original data store, work on the original, and restore the backup when the tests are over • Use transactions, to prevent commit to the data store

  14. Unit Testing with Transactions • When testing with transactions, the changes done are not really applied to the data store • Whatever commited, if tran.Complete() is not called, the transaction logic is rolled back • How to use transactions in unit tests? • Create a static TransactionScopeinstance • Initialize the transaction in TestInitialize() • Dispose the transaction in TestCleanup()

  15. Unit Testing with Transactions Live Demo

  16. How should be tested the repositories? • What parts of the repositories should our tests cover? • Test for correct behavior • Add, Delete, Get, All, etc… • Test for incorrect behavior • Test Add with Category that has NULL name

  17. Unit Testing the Repositories Live Demo

  18. Unit Testing the Services

  19. Unit Testing the Services • Testing the services layers actually means testing the controllers and the REST API • Test if controllers work correctly as C# objects • Using mocking or fake repositories • Test if the endpoints of the REST services work correctly • Check the StatusCode and Content

  20. Unit Testing of the Controllers • The Unit testing of the controllers is not much of a big deal • Test them as regular C# classes • Instantiate an object, and test its methods (actions) • The repositories can be mocked/faked for easier testing • If not mocked, the transaction technique should be used again

  21. Unit Testing Controllers with Fake Repositories • To test the controllers, repositories should be faked • i.e. create a in-memory repository that implements the IRepository<T> interface class FakeRepository<T> : IRepository<T> where T:class { IList<T> entities = new List<T>(); public T Add(T entity) { this.entities.Add(entity); return entity; } public T Get(int id) { return this.entities[id]; } … }

  22. Unit Testing Controllers with Fake Repositories (2) • With the Fake Repository present, controllers can be tested by passing their constructor a fake rep public void GetAll_OneCategoryInRepository_ReturnOneCategory() { //arrange var repository = new FakeRepository<Category>(); var categoryToAdd = new Category(){ Name = "Test category" }; repository.entities.Add(categoryToAdd); var controller = new CategoriesController(repository); //act var categoriesModels = controller.GetAll(); //assert Assert.IsTrue(categoriesModels.Count() == 1); Assert.AreEqual(categoryToAdd.Name, categoriesModels.First().Name); }

  23. Unit Testing with Fake Repositories Live Demo

  24. Unit Testing with JustMock • Creating fake repository for each and every unit test is kind of boring • Here comes the mocking • Provide objects that can mimic some functionality • JustMock supports mocking of interfaces • Creates a fake instance of an interface and implement only the functionality needed

  25. Unit Testing with JustMock (2) [TestMethod] public void GetAll_OneCategoryInRepository_ReturnsOneCategory() { //arrange var repository = Mock.Create<IRepository<Category>>(); var categoryToAdd = new Category() { Name = "Test category" }; IList<Category> categoryEntities = new List<Category>(); categoryEntities.Add(categoryToAdd); Mock.Arrange(() => repository.All()) .Returns(() => categoryEntities.AsQueryable()); var controller = new CategoriesController(repository); //act var categoryModels = controller.GetAll(); //assert Assert.IsTrue(categoryModels.Count() == 1); Assert.AreEqual(categoryToAdd.Name, categoryModels.First().Name); }

  26. Unit Testing With JustMock Live Demo

  27. More About Controllers Unit Testing • GET actions are easy to test • They return a C# objects • How to test POST actions? • They return HttpResponseMessage • Unfortunately POST actions require additional configuration due to the Request object they use

  28. Configuring POST Actions • A simple POST action: Run in unit test has a value of null public HttpResponseMessage Post(CategoryModel model) { var entity = this.categoriesRepository.Add(model); var response = Request.CreateResponse<CategoryModel>( HttpStatusCode.Created, entity); var resourceLink = Url.Link("DefaultApi", new { id = entity.Id }); response.Headers.Location= new Uri(resourceLink); return response; } • If a controller is invoked outside of WebAPI environment, the Request object is not set

  29. Configuring POST Actions (2) • The whole configuration needed for the POST to work in Unit Tests private void SetupController(ApiController controller) { var config = new HttpConfiguration(); var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/api/categories"); var route = config.Routes.MapHttpRoute(name: "DefaultApi", routeTemplate: "api/{controller}/{id}"); var routeData = new HttpRouteData(route); routeData.Values.Add("id", RouteParameter.Optional); routeData.Values.Add("controller", "categories"); controller.ControllerContext= new HttpControllerContext(config, routeData, request); controller.Request= request; controller.Request.Properties[ HttpPropertyKeys.HttpConfigurationKey] = config; controller.Request.Properties[ HttpPropertyKeys.HttpRouteDataKey] = routeData; }

  30. Unit Testing POST Actions Live Demo

  31. Integration Testing

  32. Integration Testing • Integration testing aims to cover the work of the whole application • Not small components like unit testing • Integration tests should work like a user • Test what a user sees in combination of all application components mixed together

  33. Integration Testing WebAPI • When integration testing WebAPI, controllers and their actions are thought to be working correctly • In WebAPI, integration tests should cover: • The endpoints of the RESTful services • Test if the endpoint reaches the correct action • Test the serialization of the data • Does it work with JSON/XML • Is the data serialized correctly

  34. Integration Testing WebAPI (2) • Integration testing a GET request: [TestMethod] public void GetAll_OneCategory_StatusCodeOkAndNotNullContent() { var mockRepository = Mock.Create<IRepository<Category>>(); var models = new List<Category>(); models.Add(new Category() { Name = "Test Cat" }); Mock.Arrange(() => mockRepository.All()) .Returns(() => models.AsQueryable()); var server = new InMemoryHttpServer<Category>( "http://localhost/", mockRepository); var response = server.CreateGetRequest("api/categories"); Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); Assert.IsNotNull(response.Content); }

  35. Integration Testing Live Demo

  36. Unit Testing Web Services http://academy.Telerik.com

  37. Homework • Students Database • Develop an application that holds students in schools • Students have first and last names, age, grade, a set of marks and a school • Each student can be only in a single school • Marks have subject and value • Schools have a name, location and a set of students

  38. Homework (2) • Create a database for the students database • Using MS SQL server • Create a data layer that uses the above database • Use either database-first or code-first approach • Create a repositories layer that communicates with the data layer

  39. Homework (3) • Create a services layer using the repositories and: • Use WebAPI • Introduce a REST API that allows adding and getting of students to/from the Students database • The following endpoints should be present: • GET api/students, GET api/students/{id}, • GET api/schools, GET api/schools/{id} • POST api/schools, POST api/students • GET api/students?subject=math&value=5.00 • Returns all students that have a mark for MATH and it is above 5.00

  40. Homework (4) • Write unit tests for: • The StudentsRepository • The StudentsController • Write integration tests for the StudentsController endpoints

More Related