This document discusses unit testing Web APIs using the NUnit and Moq frameworks. It provides an overview of unit testing and the NUnit and Moq frameworks. It then details setting up a test project and installing necessary packages. The document focuses on writing unit tests for the business logic layer and controllers, demonstrating how to test a ProductService class by mocking dependencies, writing test methods, and more.
The document describes setting up unit testing for a Web API project using NUnit and Moq frameworks. It includes:
1. Adding a test project and installing necessary packages like NUnit, Moq, EntityFramework, and Newtonsoft.Json.
2. Defining variables and setting up mocks for the repositories, services, and UnitOfWork classes needed for the tests.
3. Writing tests for the ProductController including getting all products, getting a product by ID, and testing exceptions.
4. Explaining how to mock the repositories to simulate database operations during the tests.
So in summary, it covers the steps to set up a Web API project for unit testing and then provides examples
Inversion of control using dependency injection in Web APIs using Unity Conta...Akhil Mittal
My article will explain how we can make our Web API service architecture loosely coupled and more flexible. We already learnt that how we can create a RESTful service using Asp.net Web API and Entity framework in my last article. If you remember we ended up in a solution with a design flaw, we’ll try to overcome that flaw by resolving the dependencies of dependent components. For those who have not followed my previous article, they can learn by having the sample project attached as a test application from my first article.
UI Controls for HTML5 to build Rich Web ApplicationsAkash Kava
JavaScripting is tedious, managing JavaScripts is even bigger pain, introducing Web Atoms, component oriented development for web for programmers with Java, Flex and Silverlight background, they can learn concepts of Dynamic Templates, Hierarchical Scope and Bindings in as little as 24 hours and start creating enterprise grade apps that run on TV, Tablets, Mobile and of course Browser.
With very little learning curve, it is easy to migrate enterprise apps from Flex/Java to HTML without learning complex JavaScript and unlimited number of libraries with extremely difficult syntax. Web Atoms runs on more configuration in XML type of Markup than code.
This document provides an overview and instructions for using the UrlRewritingNet.UrlRewrite module. It allows rewriting URLs in ASP.NET applications for search engine optimization and user-friendly URLs. Key features include rewriting URLs based on regular expressions, support for themes and master pages, and adding custom rewrite providers. Limitations include only rewriting requests handled by ASP.NET and not supporting rewriting without file extensions or cross-page postbacks without disabling security checks. The document covers installation, configuration, server settings, changing rules at runtime, and creating custom providers.
This document discusses SQL injection vulnerabilities in web applications. It begins by providing an overview and background on web applications and SQL. It then discusses comprehensively testing applications for SQL injection vulnerabilities and evaluating the results. The main section describes various SQL injection attack techniques, including authorization bypass, SELECT queries, INSERT statements, and exploiting stored procedures. It concludes by offering solutions for preventing SQL injection through data sanitization and secure coding practices.
The document provides an overview of Selenium, including:
1. An introduction to Selenium, its history and tool suite, which includes Selenium WebDriver, Selenium RC, and Selenium IDE.
2. A discussion of testing concepts like what testing is, who does testing, and when testing should start and stop in the software development lifecycle.
3. Descriptions of different types of testing like manual testing and automation testing, as well as differences between testing and debugging.
The document discusses implementing request and exception logging in ASP.NET Web APIs using NLog, Action Filters, and Exception Filters. It describes setting up NLog configuration, creating an NLogger class to handle logging, and adding an Action Filter (LoggingFilterAttribute) to log requests. It also covers adding an Exception Filter (GlobalExceptionAttribute) to log exceptions, modifying classes to support exception logging, and throwing an exception to test the exception logging.
The document describes setting up unit testing for a Web API project using NUnit and Moq frameworks. It includes:
1. Adding a test project and installing necessary packages like NUnit, Moq, EntityFramework, and Newtonsoft.Json.
2. Defining variables and setting up mocks for the repositories, services, and UnitOfWork classes needed for the tests.
3. Writing tests for the ProductController including getting all products, getting a product by ID, and testing exceptions.
4. Explaining how to mock the repositories to simulate database operations during the tests.
So in summary, it covers the steps to set up a Web API project for unit testing and then provides examples
Inversion of control using dependency injection in Web APIs using Unity Conta...Akhil Mittal
My article will explain how we can make our Web API service architecture loosely coupled and more flexible. We already learnt that how we can create a RESTful service using Asp.net Web API and Entity framework in my last article. If you remember we ended up in a solution with a design flaw, we’ll try to overcome that flaw by resolving the dependencies of dependent components. For those who have not followed my previous article, they can learn by having the sample project attached as a test application from my first article.
UI Controls for HTML5 to build Rich Web ApplicationsAkash Kava
JavaScripting is tedious, managing JavaScripts is even bigger pain, introducing Web Atoms, component oriented development for web for programmers with Java, Flex and Silverlight background, they can learn concepts of Dynamic Templates, Hierarchical Scope and Bindings in as little as 24 hours and start creating enterprise grade apps that run on TV, Tablets, Mobile and of course Browser.
With very little learning curve, it is easy to migrate enterprise apps from Flex/Java to HTML without learning complex JavaScript and unlimited number of libraries with extremely difficult syntax. Web Atoms runs on more configuration in XML type of Markup than code.
This document provides an overview and instructions for using the UrlRewritingNet.UrlRewrite module. It allows rewriting URLs in ASP.NET applications for search engine optimization and user-friendly URLs. Key features include rewriting URLs based on regular expressions, support for themes and master pages, and adding custom rewrite providers. Limitations include only rewriting requests handled by ASP.NET and not supporting rewriting without file extensions or cross-page postbacks without disabling security checks. The document covers installation, configuration, server settings, changing rules at runtime, and creating custom providers.
This document discusses SQL injection vulnerabilities in web applications. It begins by providing an overview and background on web applications and SQL. It then discusses comprehensively testing applications for SQL injection vulnerabilities and evaluating the results. The main section describes various SQL injection attack techniques, including authorization bypass, SELECT queries, INSERT statements, and exploiting stored procedures. It concludes by offering solutions for preventing SQL injection through data sanitization and secure coding practices.
The document provides an overview of Selenium, including:
1. An introduction to Selenium, its history and tool suite, which includes Selenium WebDriver, Selenium RC, and Selenium IDE.
2. A discussion of testing concepts like what testing is, who does testing, and when testing should start and stop in the software development lifecycle.
3. Descriptions of different types of testing like manual testing and automation testing, as well as differences between testing and debugging.
The document discusses implementing request and exception logging in ASP.NET Web APIs using NLog, Action Filters, and Exception Filters. It describes setting up NLog configuration, creating an NLogger class to handle logging, and adding an Action Filter (LoggingFilterAttribute) to log requests. It also covers adding an Exception Filter (GlobalExceptionAttribute) to log exceptions, modifying classes to support exception logging, and throwing an exception to test the exception logging.
Resolve dependency of dependencies using Inversion of Control and dependency ...Akhil Mittal
In my last two articles I explained how to create a RESTful service using ASP.NET Web API working with Entity Framework and resolving dependencies using Unity Container. In this article I’ll explain how to create a loosely coupled system with Unity Container and MEF(Managed Extensibility Framework) using Inversion of Control. I’ll not be explaining much theory but rather focus more on practical implementations. For the readers who are following this series, they can use their existing solution that they have created till time. For my new readers of this article, I have provided the download link for the previous source code and current source code as well.
For theory and understanding of DI and IOC you can follow the following links: Unity and Inversion of Control(IOC).
This document provides an overview of the HttpCore library, which implements fundamental aspects of the HTTP protocol to allow developing full-featured HTTP client and server applications with minimal footprint. It describes HttpCore's scope, goals, and capabilities including support for blocking and non-blocking I/O, HTTP message parsing and formatting, connection handling, and more. The document is organized into chapters covering HTTP message fundamentals, blocking and asynchronous request processing, advanced topics, and includes code examples.
The document is about the book "Learning Selenium" which teaches readers how to create automated test scripts using Selenium. It provides tutorials to get started with Selenium IDE, including how to record a test script, modify an existing script, store information from a web page. It also discusses using extensions and plugins with Selenium IDE. The book aims to help readers structure their Selenium test automation projects and provides hands-on examples testing a demo e-commerce website.
Custom URL Re-Writing/Routing using Attribute Routes in MVC 4 Web APIsAkhil Mittal
We have already learnt a lot on WebAPI. I have already explained how to create WebAPI, connect it with database using Entity Framework, resolving dependencies using Unity Container as well as using MEF. In all our sample applications we were using default route that MVC provides us for CRUD operations. In this article I’ll explain how to write your own custom routes using Attribute Routing. We’ll deal with Action level routing as well as Controller level routing. I’ll explain this in detail with the help of a sample application. My new readers can use any Web API sample they have, else you can also use the sample applications we developed in my previous articles.
Authors:
Stein Runar Bergheim
Siri Slettvåg
Asplan Viak Internet AS (AVINET)
The LoCloud Crawler Ready Tagging Tools (henceforth CRTT) are a set of experimental tools for automatically extracting structured metadata from HTML mark-‐up loaded from web documents. The objective of the CRTT is to verify if the crawling/indexing method applied by the mainstream search engines could be a viable, simplified supplement to the comprehensive Europeana ingestion process. To this end, the CRTT is validated using small institutions as a test case.
This document analyzes browser compatibility issues for AJAX-enabled web applications, focusing on Internet Explorer. It discusses standard compliance tests (Acid2 and Acid3) that test rendering of HTML, CSS, images and other technologies according to W3C and IETF specifications. The tests show that while Safari, Firefox, Chrome, and Opera score well, IE scores poorly (20/100 for IE8 in Acid3). Case studies show that some major web applications like Apple MobileMe do not support IE due to standards compliance and performance issues. The document also discusses browser market share trends showing a decline in IE's share.
This document provides an overview and details of a forms application developed using the Spring Framework. It describes setting up the Spring Tool Suite environment, configuring dependencies and files, developing models, repositories, services and controllers to manage users, forms, questions and answers. It also covers implementing security and setting up the database schema and package structure. Views for login, registration, and managing forms, questions and answers are discussed.
This document provides a summary of Abdulrahman Emad's technical and business achievements in 2015. It includes sections on business achievements on various projects, a documentation index, summaries of emails on model binding, technical enhancements, TPL dataflow, new development themes, software quality, and string manipulation. It also provides a table of contents and quotes section.
webapp2 is a lightweight Python web framework compatible with Google App Engine’s webapp.
webapp2 is a single file that follows the simplicity of webapp, but improves it in some ways: it extends webapp to offer
better URI routing and exception handling, a full featured response object and a more flexible dispatching mechanism.
webapp2 also offers the package webapp2_extras with several optional utilities: sessions, localization, internationalization,
domain and subdomain routing, secure cookies and support for threaded environments.
webapp2 can also be used outside of Google App Engine, independently of the App Engine SDK.
For a complete description of how webapp2 improves webapp, see features.
The document is a software requirements specification for a system to perform record matching over query results from multiple web databases. It describes the purpose, conventions, intended users, product scope, and references. It provides an overall description of the product perspective and functions, describes user classes and characteristics, operating environment, design constraints, and documentation. It outlines external interface requirements including user interfaces, hardware/software interfaces, and communications interfaces. It details system features and other non-functional requirements around performance, safety, security, quality, and business rules.
The Opendelight framework encompasses multi-tier architecture of web application, and is based on several design patterns including most notably Model-View-Controller (MVC).
This document is the Neo4j Manual v1.8.M01 which provides an introduction to graph database concepts, tutorials on using Neo4j from Java and Python, a reference section on Neo4j capabilities and transactions, and sections on operations, tools, and contributing to the Neo4j community. It is published by Neo Technology under a Creative Commons license and covers topics such as nodes, relationships, properties, paths, and the Cypher query language.
Big data - ‘Big Data’ is similar to ‘small data’, but bigger in size.
But having data bigger it requires different approaches:Techniques, tools and architecture.
Web development- React.js,angular js,Vue.js
Mobile application development-API in mobile applications (cURL API),Develop in mobile applications (react-native)
elementary OS
Concurrency
This document provides an introduction to PHP-Nuke, an open source content management system. It discusses the purpose and features of PHP-Nuke, including its use for websites, intranets, e-commerce, and more. The document also provides a brief history of PHP-Nuke, noting it was created in 1998 as a way to manage a news site and distribute content. It describes PHP-Nuke as using PHP and MySQL to allow users to submit and discuss content through a web-based interface.
This document provides information about customizing and programming for the PHP-Nuke content management system, including:
- An overview of PHP-Nuke's installation, structure, modules, blocks, and customization options.
- Instructions for creating new blocks and modules to extend PHP-Nuke's functionality.
- Details on PHP-Nuke's directory structure, databases tables, and security best practices.
- Guidelines for modifying themes, templates, and the user interface.
The document is intended as a reference for PHP-Nuke administrators and programmers to manage sites and develop additional functionality through blocks and modules.
The document provides an overview of Application Builder and instructions for getting started using it. Application Builder is a tool for creating search applications without coding. It allows configuring facets, search results details, and content rendering. The document explains how Application Builder is preconfigured for clean MarkLogic installations and how it is handled during upgrades. It also provides instructions for starting Application Services and building a sample movies application using the tool's interface.
1. The document provides an overview of the Spring Test Framework including memos, gifs, theory, humor and a demo. Technologies covered include Spring 4, Spring Boot 1.5, Docker, Gradle, H2 and PostgreSQL.
2. Testing concepts such as the test pyramid, F.I.R.S.T principles, unit vs integration testing are discussed. The benefits of testing such as maintainability and reducing errors are also summarized.
3. Key aspects of the Spring framework are highlighted including inversion of control, dependency injection, Spring MVC, Spring Data and Spring Boot features like autoconfiguration. Spring testing annotations and customization are also outlined.
This document provides a summary of a project that developed a vendor connection web application using the CodeIgniter PHP framework. It discusses the technologies used including CodeIgniter, Bootstrap, HTML5 and CSS3. It describes the system development process, including system analysis, database design, and installation of CodeIgniter. It outlines key features of the application such as login, home page, vendor list, order status, and order viewing. The purpose of the project is to introduce CodeIgniter and Bootstrap while providing an example application for students to learn web development.
This document discusses content negotiation in ASP.NET Web API 2. It explains what content negotiation is, why it is important, and how to implement it in Web API. Content negotiation allows a client to specify the desired response format using request headers like Accept and Content-Type. Web API uses formatters to serialize the response into the requested format. The document provides examples of configuring formatters to support different media types and customize the JSON output. It also describes how the content negotiation pipeline in Web API works to select the appropriate formatter based on the request headers.
The document discusses new and improved debugging features in Visual Studio 2015, including easier breakpoint configuration with an inline toolbar, simplified context menus, and settings windows that appear as peek windows. It also covers breakpoint conditions that allow hitting a breakpoint based on the number of hits or a conditional expression. Breakpoint actions allow logging messages to the output window. Additionally, the improved Error List in VS 2015 displays all errors at once, allows filtering by severity and error code, and links error codes to documentation.
Resolve dependency of dependencies using Inversion of Control and dependency ...Akhil Mittal
In my last two articles I explained how to create a RESTful service using ASP.NET Web API working with Entity Framework and resolving dependencies using Unity Container. In this article I’ll explain how to create a loosely coupled system with Unity Container and MEF(Managed Extensibility Framework) using Inversion of Control. I’ll not be explaining much theory but rather focus more on practical implementations. For the readers who are following this series, they can use their existing solution that they have created till time. For my new readers of this article, I have provided the download link for the previous source code and current source code as well.
For theory and understanding of DI and IOC you can follow the following links: Unity and Inversion of Control(IOC).
This document provides an overview of the HttpCore library, which implements fundamental aspects of the HTTP protocol to allow developing full-featured HTTP client and server applications with minimal footprint. It describes HttpCore's scope, goals, and capabilities including support for blocking and non-blocking I/O, HTTP message parsing and formatting, connection handling, and more. The document is organized into chapters covering HTTP message fundamentals, blocking and asynchronous request processing, advanced topics, and includes code examples.
The document is about the book "Learning Selenium" which teaches readers how to create automated test scripts using Selenium. It provides tutorials to get started with Selenium IDE, including how to record a test script, modify an existing script, store information from a web page. It also discusses using extensions and plugins with Selenium IDE. The book aims to help readers structure their Selenium test automation projects and provides hands-on examples testing a demo e-commerce website.
Custom URL Re-Writing/Routing using Attribute Routes in MVC 4 Web APIsAkhil Mittal
We have already learnt a lot on WebAPI. I have already explained how to create WebAPI, connect it with database using Entity Framework, resolving dependencies using Unity Container as well as using MEF. In all our sample applications we were using default route that MVC provides us for CRUD operations. In this article I’ll explain how to write your own custom routes using Attribute Routing. We’ll deal with Action level routing as well as Controller level routing. I’ll explain this in detail with the help of a sample application. My new readers can use any Web API sample they have, else you can also use the sample applications we developed in my previous articles.
Authors:
Stein Runar Bergheim
Siri Slettvåg
Asplan Viak Internet AS (AVINET)
The LoCloud Crawler Ready Tagging Tools (henceforth CRTT) are a set of experimental tools for automatically extracting structured metadata from HTML mark-‐up loaded from web documents. The objective of the CRTT is to verify if the crawling/indexing method applied by the mainstream search engines could be a viable, simplified supplement to the comprehensive Europeana ingestion process. To this end, the CRTT is validated using small institutions as a test case.
This document analyzes browser compatibility issues for AJAX-enabled web applications, focusing on Internet Explorer. It discusses standard compliance tests (Acid2 and Acid3) that test rendering of HTML, CSS, images and other technologies according to W3C and IETF specifications. The tests show that while Safari, Firefox, Chrome, and Opera score well, IE scores poorly (20/100 for IE8 in Acid3). Case studies show that some major web applications like Apple MobileMe do not support IE due to standards compliance and performance issues. The document also discusses browser market share trends showing a decline in IE's share.
This document provides an overview and details of a forms application developed using the Spring Framework. It describes setting up the Spring Tool Suite environment, configuring dependencies and files, developing models, repositories, services and controllers to manage users, forms, questions and answers. It also covers implementing security and setting up the database schema and package structure. Views for login, registration, and managing forms, questions and answers are discussed.
This document provides a summary of Abdulrahman Emad's technical and business achievements in 2015. It includes sections on business achievements on various projects, a documentation index, summaries of emails on model binding, technical enhancements, TPL dataflow, new development themes, software quality, and string manipulation. It also provides a table of contents and quotes section.
webapp2 is a lightweight Python web framework compatible with Google App Engine’s webapp.
webapp2 is a single file that follows the simplicity of webapp, but improves it in some ways: it extends webapp to offer
better URI routing and exception handling, a full featured response object and a more flexible dispatching mechanism.
webapp2 also offers the package webapp2_extras with several optional utilities: sessions, localization, internationalization,
domain and subdomain routing, secure cookies and support for threaded environments.
webapp2 can also be used outside of Google App Engine, independently of the App Engine SDK.
For a complete description of how webapp2 improves webapp, see features.
The document is a software requirements specification for a system to perform record matching over query results from multiple web databases. It describes the purpose, conventions, intended users, product scope, and references. It provides an overall description of the product perspective and functions, describes user classes and characteristics, operating environment, design constraints, and documentation. It outlines external interface requirements including user interfaces, hardware/software interfaces, and communications interfaces. It details system features and other non-functional requirements around performance, safety, security, quality, and business rules.
The Opendelight framework encompasses multi-tier architecture of web application, and is based on several design patterns including most notably Model-View-Controller (MVC).
This document is the Neo4j Manual v1.8.M01 which provides an introduction to graph database concepts, tutorials on using Neo4j from Java and Python, a reference section on Neo4j capabilities and transactions, and sections on operations, tools, and contributing to the Neo4j community. It is published by Neo Technology under a Creative Commons license and covers topics such as nodes, relationships, properties, paths, and the Cypher query language.
Big data - ‘Big Data’ is similar to ‘small data’, but bigger in size.
But having data bigger it requires different approaches:Techniques, tools and architecture.
Web development- React.js,angular js,Vue.js
Mobile application development-API in mobile applications (cURL API),Develop in mobile applications (react-native)
elementary OS
Concurrency
This document provides an introduction to PHP-Nuke, an open source content management system. It discusses the purpose and features of PHP-Nuke, including its use for websites, intranets, e-commerce, and more. The document also provides a brief history of PHP-Nuke, noting it was created in 1998 as a way to manage a news site and distribute content. It describes PHP-Nuke as using PHP and MySQL to allow users to submit and discuss content through a web-based interface.
This document provides information about customizing and programming for the PHP-Nuke content management system, including:
- An overview of PHP-Nuke's installation, structure, modules, blocks, and customization options.
- Instructions for creating new blocks and modules to extend PHP-Nuke's functionality.
- Details on PHP-Nuke's directory structure, databases tables, and security best practices.
- Guidelines for modifying themes, templates, and the user interface.
The document is intended as a reference for PHP-Nuke administrators and programmers to manage sites and develop additional functionality through blocks and modules.
The document provides an overview of Application Builder and instructions for getting started using it. Application Builder is a tool for creating search applications without coding. It allows configuring facets, search results details, and content rendering. The document explains how Application Builder is preconfigured for clean MarkLogic installations and how it is handled during upgrades. It also provides instructions for starting Application Services and building a sample movies application using the tool's interface.
1. The document provides an overview of the Spring Test Framework including memos, gifs, theory, humor and a demo. Technologies covered include Spring 4, Spring Boot 1.5, Docker, Gradle, H2 and PostgreSQL.
2. Testing concepts such as the test pyramid, F.I.R.S.T principles, unit vs integration testing are discussed. The benefits of testing such as maintainability and reducing errors are also summarized.
3. Key aspects of the Spring framework are highlighted including inversion of control, dependency injection, Spring MVC, Spring Data and Spring Boot features like autoconfiguration. Spring testing annotations and customization are also outlined.
This document provides a summary of a project that developed a vendor connection web application using the CodeIgniter PHP framework. It discusses the technologies used including CodeIgniter, Bootstrap, HTML5 and CSS3. It describes the system development process, including system analysis, database design, and installation of CodeIgniter. It outlines key features of the application such as login, home page, vendor list, order status, and order viewing. The purpose of the project is to introduce CodeIgniter and Bootstrap while providing an example application for students to learn web development.
This document discusses content negotiation in ASP.NET Web API 2. It explains what content negotiation is, why it is important, and how to implement it in Web API. Content negotiation allows a client to specify the desired response format using request headers like Accept and Content-Type. Web API uses formatters to serialize the response into the requested format. The document provides examples of configuring formatters to support different media types and customize the JSON output. It also describes how the content negotiation pipeline in Web API works to select the appropriate formatter based on the request headers.
The document discusses new and improved debugging features in Visual Studio 2015, including easier breakpoint configuration with an inline toolbar, simplified context menus, and settings windows that appear as peek windows. It also covers breakpoint conditions that allow hitting a breakpoint based on the number of hits or a conditional expression. Breakpoint actions allow logging messages to the output window. Additionally, the improved Error List in VS 2015 displays all errors at once, allows filtering by severity and error code, and links error codes to documentation.
This document discusses code refactoring techniques in Visual Studio 2015, including inline temporary variables and introducing local variables. It provides an example C# class with a method to fetch products above a certain price, and shows how Visual Studio's code refactoring suggestions can optimize the method in multiple steps. These include removing temporary variables, converting the method to an expression-bodied member, and reducing the code to a single line. The document emphasizes that code refactoring requires an understanding of how the changes will affect the code.
The document discusses renaming features in Visual Studio 2015. It describes how VS2015 provides renaming assistance through suggestions from the light bulb icon and previews changes before renaming. The renaming window allows renaming variables, methods, properties, classes, parameters and strings. It can also rename code comments and detect conflicts if the new name already exists. Renaming occurs inline and on the fly. The examples demonstrate renaming a variable, method, and parameter across multiple files. VS2015 helps optimize code through intelligent and automated renaming.
The document discusses Visual Studio's live static code analysis feature. It explains that this feature analyzes code in real-time as it is written, without requiring compilation, to detect errors and potential issues based on installed code analyzers. The document demonstrates how to install and use code analyzers through examples, showing how analyzers detect issues and provide suggestions to fix problems directly in the code editor through light bulb notifications. It provides a case study walking through fixing various issues detected in sample code using suggestions from an analyzer to iteratively improve the code quality.
The document discusses the code assistance features of Visual Studio 2015. It provides examples of how the light bulb icon displays potential fixes for syntax errors and missing code. It also shows how refactoring suggestions are provided to optimize code, such as removing unused namespaces or changing a method to directly return a value rather than using a temporary variable. The light bulb icon assists with code completion, error fixing, and refactoring to improve code quality and developer productivity.
Release planning is a challenging but important part of the agile development process. There are two main approaches to release planning: fixed timeline and fixed scope of work. With a fixed timeline, the deadline cannot be extended and functionality may need to be cut, while a fixed scope defines what must be included regardless of timeline. The objective of release planning is to baseline the product roadmap and team commitments, while allowing flexibility based on which approach is chosen.
This document discusses extending OData support in ASP.NET Web APIs. It provides an introduction to OData and the roadmap for a RESTful Web API series. It describes setting up a solution to add OData support and modifying existing API endpoints to be OData enabled. This allows queries to support options like $top, $filter, $orderby and more to filter, sort, page and select data from the server.
Generic Repository Pattern in MVC3 Application with Entity FrameworkAkhil Mittal
This document discusses implementing a generic repository pattern and unit of work pattern in an MVC application using Entity Framework. It begins by introducing the concepts of a generic repository and unit of work. It then shows how to create a generic repository class that can be used for any entity. A unit of work class is created to manage transactions and repositories. Properties on the unit of work class provide access to repositories without having to create separate classes. CRUD operations on entities are demonstrated using the generic repository through the unit of work. This completes the tutorial on implementing these patterns to reduce redundant code and complexity in an MVC application.
Repository Pattern in MVC3 Application with Entity FrameworkAkhil Mittal
The document discusses implementing a repository pattern in an MVC application using Entity Framework. It begins with an introduction and roadmap of previous articles. It then discusses the benefits of a repository pattern in abstracting the data access layer from business logic. Steps are provided to create a sample repository interface and class to implement basic CRUD operations on a User entity, abstracting the data access code from the controller. The repository class uses the Entity Framework context to perform operations while resolving tight coupling issues between layers. It concludes that while this implementation works for a single entity, a generic repository will be needed to cleanly support multiple entities without duplication.
MVC Application using EntityFramework Code-First approach Part4Akhil Mittal
This document discusses connecting an MVC application to a database using Entity Framework's Code First approach. It explains that with Code First, domain models are designed first before the database is automatically generated. The steps shown create a DbContext class that inherits from DbContext and defines a DbSet for the User model. A connection string is added and the DbContext is used instead of the prior Entity Data Model classes. When run, the database is dynamically generated based on the model, allowing CRUD operations on the User table through the application and Entity Framework.
Learning MVC Part 3 Creating MVC Application with EntityFrameworkAkhil Mittal
This document discusses connecting an existing MVC application to a database using Entity Framework instead of LINQ to SQL. It provides steps to generate an Entity Data Model from an existing database, generate strongly typed entity classes, and modify the application's controllers to use the Entity Framework context instead of the LINQ to SQL context. The key steps are: 1) Adding an Entity Data Model file and generating entity classes; 2) Modifying controllers to use the Entity Framework context instead of LINQ to SQL; 3) Binding views to the generated entity classes. The document emphasizes that Entity Framework automates CRUD operations and allows focusing on business logic rather than data access code.
This document discusses creating an MVC application from scratch using LINQ to SQL to perform CRUD operations on a database. It covers:
1. Creating an empty MVC project and adding controllers, views and models
2. Creating a sample database and using LINQ to SQL for communication between the MVC app and database
3. Performing CRUD operations in the MVC app by querying the database and passing data between controllers and views
This document introduces the MVC architecture and separation of concerns. It outlines a 6 part roadmap to cover MVC fundamentals and implementing it with Entity Framework. Part 1 introduces MVC, defining the roles of models, views, and controllers. It explains how MVC separates the application into independent and reusable components for the model, views for presentation, and controllers for handling requests. This separation aims to improve maintainability and extensibility of applications.
This document discusses implementing security in a Web API using basic authentication and token-based authorization. It introduces basic authentication as a means of validating a user's credentials through a username and password sent in the request header. Token-based authorization is described as sending a token to authenticated users that allows them to access other resources. The document then outlines steps to create a user service, implement basic authentication using an authentication filter, and implement token-based authorization by setting up databases, services, and controllers and marking them with an authorization filter. Maintaining sessions with tokens is also briefly mentioned.
C sharp and asp.net interview questionsAkhil Mittal
The document provides summaries of common questions and answers related to ASP.NET, C#, and the .NET framework. It defines view state as storing the current property settings of an ASP.NET page and controls to detect form submissions. It explains that user controls allow reusing ASP.NET pages as controls, and validation controls perform input checking on server controls. The document also distinguishes between Response.Write and Response.Output.Write, and lists page life cycle methods like Init, Load, and Unload.
This document provides answers to common ASP.NET interview questions. It begins with questions about the differences between custom controls and user controls, ASP session state and ASP.NET session state, and datasets versus recordsets in ADO.NET. Subsequent questions cover topics like view state, authentication, caching, validation controls, and working with data controls.
Diving in OOP (Day 1) : Polymorphism and Inheritance (Early Binding/Compile T...Akhil Mittal
I have been writing a lot about advanced topics like MVC, Entity Framework, Repository Patterns etc., my priority always remains to cover the topic as a whole, so that a reader do not have to search for missing links anywhere else. My this article will cover almost every OOPS concept that a novice/beginner developer hunt for, and not only beginners, the article’s purpose is to be helpful to experience professionals also who need to sometimes brush-up their concepts or who prepare for interviews .
Diving in OOP (Day 6): Understanding Enums in C# (A Practical Approach)Akhil Mittal
My article of the series “Diving in OOP” will explain enum datatype in C#. We’ll learn by doing hands on lab and not only by theory. We’ll explore the power of enum and will cover almost every scenario in which we can use enum. We’ll follow a practical approach of learning to understand this concept. We may come across complex examples to understand the concept more deeply.
Diving into OOP (Day 5): All About C# Access Modifiers (Public/Private/Protec...Akhil Mittal
Access modifiers (or access specifiers) are keywords in object-oriented languages that set the accessibility of classes, methods, and other members. Access modifiers are a specific part of programming language syntax used to facilitate the encapsulation of components.
Diving into OOP (Day 5): All About C# Access Modifiers (Public/Private/Protec...
RESTful Day 7
1. RESTful Day #7: Unit Testing and Integration
Testing in WebAPI using NUnit and Moq
framework (Part1)-Akhil Mittal.
Table of Contents
Table of Contents......................................................................................................................................... 1
Introduction ................................................................................................................................................ 2
Roadmap..................................................................................................................................................... 2
Unit Tests .................................................................................................................................................... 3
NUnit .......................................................................................................................................................... 4
Moq Framework.......................................................................................................................................... 6
Setup Solution ............................................................................................................................................. 7
Testing Business Services ........................................................................................................................... 12
Step 1: Test Project ..............................................................................................................................................12
Step 2: Install NUnit package ................................................................................................................................13
Step 3: Install Moq framework..............................................................................................................................14
Step 4: Install Entity Framework ...........................................................................................................................15
Step 5: Install AutoMapper...................................................................................................................................15
Step 6: References................................................................................................................................................15
TestHelper ...........................................................................................................................................................15
ProductService Tests ............................................................................................................................................18
Tests Setup......................................................................................................................................................................................18
Declare variables.......................................................................................................................................................18
Write Test Fixture Setup ...........................................................................................................................................19
Write Test Fixture Tear Down...................................................................................................................................19
Write Test Setup .......................................................................................................................................................20
Write Test Tear down ...............................................................................................................................................20
Mocking Repository ..................................................................................................................................................21
Initialize UnitOfWork and Service.............................................................................................................................22
1. GetAllProductsTest () .............................................................................................................................................................23
2. GetAllProductsTestForNull ()..................................................................................................................................................26
3. GetProductByRightIdTest ()....................................................................................................................................................27
4. GetProductByWrongIdTest () .................................................................................................................................................29
2. 5. AddNewProductTest () ...........................................................................................................................................................30
6. UpdateProductTest ().............................................................................................................................................................32
7. DeleteProductTest () ..............................................................................................................................................................33
TokenService Tests...............................................................................................................................................40
Tests Setup......................................................................................................................................................................................40
Declare variables.......................................................................................................................................................40
Write Test Fixture Setup ...........................................................................................................................................41
Write Test Fixture Tear Down...................................................................................................................................41
Write Test Setup .......................................................................................................................................................42
Write Test Tear down ...............................................................................................................................................42
Mocking Repository ..................................................................................................................................................43
1. GenerateTokenByUseridTest () ..............................................................................................................................................44
2. ValidateTokenWithRightAuthToken () ...................................................................................................................................46
3. ValidateTokenWithWrongAuthToken ().................................................................................................................................46
UserService Tests .................................................................................................................................................47
WebAPI Tests.......................................................................................................................................................53
Conclusion................................................................................................................................................. 53
Introduction
We have been learning a lot in WebAPI. We covered almost all the techniques required to build a robust and a
full stack REST service using asp.net WebAPI, right from creating a service to making it a secure and ready to
use boilerplate with enterprise level applications. In this article we’ll learn on how to focus on test driven
development and write unit tests for our service endpoints and business logic. I’ll use NUnit and Moq
framework to write test cases for business logic layer and controller methods. I’ll cover less theory and focus
more on practical implementations on how to use these frameworks to write unit tests. I have segregated the
article into two parts. First part focusses on testing business logic and class libraries created as
BusinessServices in our code base. Second part will focus on testing a Web API. The purpose of segregation is
simple; the scope of this article is very large and may turn up into a very large post which would be not easy to
read in a go.
Roadmap
Following is the roadmap I have setup to learn WebAPI step by step,
3. RESTful Day #1: Enterprise level application architecture with Web APIs using Entity Framework, Generic
Repository pattern and Unit of Work.
RESTful Day #2: Inversion of control using dependency injection in Web APIs using Unity Container and
Bootstrapper.
RESTful Day #3: Resolve dependency of dependencies using Inversion of Control and dependency injection in
Asp.net Web APIs with Unity Container and Managed Extensibility Framework (MEF).
RESTful Day #4: Custom URL Re-Writing/Routing using Attribute Routes in MVC 4 Web APIs.
RESTful Day #5: Basic Authentication and Token based custom Authorization in Web APIs using Action Filters.
RESTful Day #6: Request logging and Exception handing/logging in Web APIs using Action Filters, Exception
Filters and NLog.
RESTful Day #7: Unit Testing and Integration Testing in WebAPI using NUnit and Moq framework (Part1).
RESTful Day #8: Unit Testing and Integration Testing in WebAPI using NUnit and Moq framework (Part 2).
RESTful Day #9: Extending OData support in ASP.NET Web APIs.
I’ll purposely use Visual Studio 2010 and .net Framework 4.0 because there are few implementations that are
very hard to find in .Net Framework 4.0, but I’ll make it easy by showing how we can do it.
Unit Tests
“Unit tests allow you to make big changes to code quickly. You know it works now because you’ve run the
tests, when you make the changes you need to make, you need to get the tests working again. This saves
hours.” I got this from a post at stack overflow, and I completely agree to this statement.
4. A good unit test helps a developer to understand his code and most importantly the business logic. Unit tests
help to understand all the aspects of business logic, right from the desired input and output to the conditions
where the code can fail. A code having a well written unit tests have very less chances to fail provided the unit
tests cover all the test cases required to execute.
NUnit
There are various frameworks available for Unit tests. NUnit is the one that I prefer. NUnit gels well with .Net
and provide flexibility to write unit tests without hassle. It has meaningful and self-explanatory properties and
class names that help developer to write the tests in an easy way. NUnit provides an easy to use interactive
GUI where you can run the tests and get the details .It shows the number of tests passed or fail in a beautiful
fashion and also gives the stack trace in case any test fails, thereby enabling you to perform the first level of
debugging at the GUI itself. I suggest downloading and installing NUnit on your machine for running the tests.
We’ll use NUnit GUI after we write all the tests. I normally use inbuilt GUI of NUnit provided by Re-sharper
integrated in my Visual Studio. Since Re-sharper is a paid library only few developers may have it integrated,
so I suggest you to use NUnit GUI to run the tests. Since we are using Visual Studio 2010, we need to use the
older version of NUnit i.e. 2.6.4. You can download and run the .msi and install on your machine following this
URL.
5. Once you finish installation, you’ll see NUnit installed in your installed items on your machine as shown in
below image,
6. Moq Framework
Moq is a simple and straight forward library to mock the objects in C#. We can mock data, repositories classes
and instances with the help of mock library. So when we write unit tests, we do not execute them on the
actual class instances, instead perform in-memory unit testing by making proxy of class objects. Like NUnit,
7. Moq library classes are also easy to use and understand. Almost all of its methods, classes and interfaces
names are self-explanatory.
Following is the list taken from Wikipedia on why to use mock objects,
The object supplies non-deterministic results (e.g., the current time or the current temperature);
Has states that are not easy to create or reproduce (e.g., a network error);
Is slow (e.g., a complete database, which would have to be initialized before the test);
Does not yet exist or may change behavior;
Would have to include information and methods exclusively for testing purposes (and not for its actual
task).
So whatever test we write, we actually execute that on test data and proxy objects i.e. not the instances of
real classes. We’ll use Moq to mock data and repositories so that we do not hit database again and again for
executing unit tests. You can read more about Moq in this article.
Setup Solution
I’ll use this article to explain how to write unit tests for business logic i.e. covering our business logic layer and
for WebAPI controllers. The scope of Unit tests should not be only limited to business logic or endpoints but
should spread over all publically exposed logics like filters and handlers as well. Well written unit tests should
cover almost all the code. One can track the code coverage through some of the tools available online. We’ll
not test filters and common classes but will focus on controllers and business logic layer and get an idea of
how to proceed with unit tests. I’ll use the same source code that we used till Day# 6 of the series and will
proceed with the latest code base that we got out of last article of the series. Code base is available for
download with this post. When you take the code base from my last article and open it in visual studio, you’ll
see the project structure something like as shown in below image,
8. IUnitOfWork is the new interface that I have added just to facilitate interface driven development. It helps in
mocking objects and improved structure and readability. Just open the visual studio and add a new interface
named IUnitOfWork under UnitOfWork folder in DataModel project and define the properties used in
UnitOfWork class as shown below,
Now, go to UnitOfWork class and inherit that class using this interface, so UnitOfWork class becomes
something like this,
#region Using Namespaces...
using System;
using System.Collections.Generic;
using System.Data.Entity;
9. using System.Diagnostics;
using System.Data.Entity.Validation;
using DataModel.GenericRepository;
#endregion
namespace DataModel.UnitOfWork
{
/// <summary>
/// Unit of Work class responsible for DB transactions
/// </summary>
public class UnitOfWork : IDisposable, IUnitOfWork
{
#region Private member variables...
private readonly WebApiDbEntities _context = null;
private GenericRepository<User> _userRepository;
private GenericRepository<Product> _productRepository;
private GenericRepository<Token> _tokenRepository;
#endregion
public UnitOfWork()
{
_context = new WebApiDbEntities();
}
#region Public Repository Creation properties...
/// <summary>
/// Get/Set Property for product repository.
/// </summary>
public GenericRepository<Product> ProductRepository
{
get
{
if (this._productRepository == null)
this._productRepository = new GenericRepository<Product>(_context);
return _productRepository;
}
}
/// <summary>
/// Get/Set Property for user repository.
/// </summary>
public GenericRepository<User> UserRepository
{
get
{
if (this._userRepository == null)
this._userRepository = new GenericRepository<User>(_context);
return _userRepository;
}
}
/// <summary>
/// Get/Set Property for token repository.
10. /// </summary>
public GenericRepository<Token> TokenRepository
{
get
{
if (this._tokenRepository == null)
this._tokenRepository = new GenericRepository<Token>(_context);
return _tokenRepository;
}
}
#endregion
#region Public member methods...
/// <summary>
/// Save method.
/// </summary>
public void Save()
{
try
{
_context.SaveChanges();
}
catch (DbEntityValidationException e)
{
var outputLines = new List<string>();
foreach (var eve in e.EntityValidationErrors)
{
outputLines.Add(string.Format("{0}: Entity of type "{1}" in state
"{2}" has the following validation errors:", DateTime.Now, eve.Entry.Entity.GetType().Name,
eve.Entry.State));
foreach (var ve in eve.ValidationErrors)
{
outputLines.Add(string.Format("- Property: "{0}", Error: "{1}"",
ve.PropertyName, ve.ErrorMessage));
}
}
System.IO.File.AppendAllLines(@"C:errors.txt", outputLines);
throw e;
}
}
#endregion
#region Implementing IDiosposable...
#region private dispose variable declaration...
private bool disposed = false;
#endregion
/// <summary>
/// Protected Virtual Dispose method
/// </summary>
/// <param name="disposing"></param>
11. protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
Debug.WriteLine("UnitOfWork is being disposed");
_context.Dispose();
}
}
this.disposed = true;
}
/// <summary>
/// Dispose method
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
}
So, now all the interface members defined in IUnitOfWork are implemented in UnitOfWork class,
public interface IUnitOfWork
{
#region Properties
GenericRepository<Product> ProductRepository { get; }
GenericRepository<User> UserRepository { get; }
GenericRepository<Token> TokenRepository { get; }
#endregion
#region Public methods
/// <summary>
/// Save method.
/// </summary>
void Save();
#endregion
}
Doing this will not change the functionality of our existing code, but we also need to update the business
services with this Interface. We’ll pass this IUnitOfWork interface instance inside services constructors instead
of directly using UnitOfWork class.
private readonly IUnitOfWork _unitOfWork;
public ProductServices(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
12. So our User service, Token service and product service constructors becomes as shown below,
Product Service:
User Service:
Token Service:
Testing Business Services
We’ll start writing unit tests for BusinessServices project.
Step 1: Test Project
13. Add a simple class library in the existing visual studio and name it BusinessServices.Tests. Open Tools->Library
Packet Manager->Packet manager Console to open the package manager console window. We need to install
come packages before we proceed.
Step 2: Install NUnit package
In package manager console, select BusinessServices.Tests as default project and write command “Install-
Package NUnit –Version 2.6.4”. If you do not mention the version, the PMC (Package manage Console) will try
to download the latest version of NUnit nugget package but we specifically need 2.6.4, so we need to mention
the version. Same applies to when you try to install any such package from PMC
14. After successfully installed, you can see the dll reference in project references i.e. nunit.framework,
Step 3: Install Moq framework
Install the framework on the same project in the similar way as explained in Step 2. Write command “Install-
Package Moq” .Here we use latest version of Moq
Therefore added dll,
16. We will require few helper files that would be needed in BusinessServices.Tests project and in our
WebAPI.Tests project that we’ll create later. To place all the helper files, I have created one more class library
project named TestHelper. Just right click the solution and add new project named TestHelper and add a class
named DataInitializer.cs into it. This class contains three simple methods to fetch i.e. User’s, Product’s and
Token’s dummy data. You can use following code as the class implementation,
using System;
using System.Collections.Generic;
using DataModel;
namespace TestsHelper
{
/// <summary>
/// Data initializer for unit tests
/// </summary>
public class DataInitializer
{
/// <summary>
/// Dummy products
/// </summary>
/// <returns></returns>
public static List<Product> GetAllProducts()
{
var products = new List<Product>
{
new Product() {ProductName = "Laptop"},
new Product() {ProductName = "Mobile"},
new Product() {ProductName = "HardDrive"},
new Product() {ProductName = "IPhone"},
new Product() {ProductName = "IPad"}
};
return products;
}
/// <summary>
/// Dummy tokens
/// </summary>
/// <returns></returns>
public static List<Token> GetAllTokens()
{
var tokens = new List<Token>
{
new Token()
{
AuthToken = "9f907bdf-f6de-425d-be5b-b4852eb77761",
ExpiresOn = DateTime.Now.AddHours(2),
IssuedOn = DateTime.Now,
UserId = 1
},
new Token()
{
AuthToken = "9f907bdf-f6de-425d-be5b-b4852eb77762",
ExpiresOn = DateTime.Now.AddHours(1),
IssuedOn = DateTime.Now,
17. UserId = 2
}
};
return tokens;
}
/// <summary>
/// Dummy users
/// </summary>
/// <returns></returns>
public static List<User> GetAllUsers()
{
var users = new List<User>
{
new User()
{
UserName = "akhil",
Password = "akhil",
Name = "Akhil Mittal",
},
new User()
{
UserName = "arsh",
Password = "arsh",
Name = "Arsh Mittal",
},
new User()
{
UserName = "divit",
Password = "divit",
Name = "Divit Agarwal",
}
};
return users;
}
}
}
In the above class GetAllUsers() fetches dummy data for users, GetAllProducts() fetches dummy data for
Products and GetAllTokens() method fetches dummy data for Tokens. So now, our solution has two new
projects as shown below,
Add DataModel project reference to TestHelper project and TestHelper project reference to BusinessServices.Tests
project.
18. ProductService Tests
We’ll start with setting up the project and setting up the pre-requisites for tests and gradually move on to actual tests.
Tests Setup
We’ll proceed with creating ProductServices tests. Add a new class named ProductServicesTests.cs in
BusinessServices.Tests project.
Declare variables
Define the private variables that we’ll use in the class to write tests,
#region Variables
private IProductServices _productService;
private IUnitOfWork _unitOfWork;
private List<Product> _products;
private GenericRepository<Product> _productRepository;
private WebApiDbEntities _dbEntities;
#endregion
Variable declarations are self-explanatory where _productService will hold mock for ProductServices,
_unitOfWork for UnitOfWork class, _products will hold dummy products from DataInitializer class of
TestHelper project, _productRepository and _dbEntities holds mock for Product Repository and
WebAPIDbEntities from DataModel project respectively
19. Write Test Fixture Setup
Test fixture setup is written as a onetime setup for all the tests. It is like a constructor in terms of classes.
When we start executing setup, this is the first method to be executed. In this method we’ll populate the
dummy products data and decorate this method with the [TestFixtureSetUp] attribute at the top that tells
compiler that the particular method is a TestFixtureSetup. [TestFixtureSetUp] attribute is the part of NUnit
framework, so include it in the class as a namespace i.e. using NUnit.Framework;. Following is the code for
TestFixtureSetup.
#region Test fixture setup
/// <summary>
/// Initial setup for tests
/// </summary>
[TestFixtureSetUp]
public void Setup()
{
_products = SetUpProducts();
}
#endregion
private static List<Product> SetUpProducts()
{
var prodId = new int();
var products = DataInitializer.GetAllProducts();
foreach (Product prod in products)
prod.ProductId = ++prodId;
return products;
}
SetUpproducts() method fetches products from DataInitializer class and not from database.It also and assigns
a unique id to each product by iterating them. The result data is assigned to _products list to be used in
setting up mock repository and in every individual test for comparison of actual vs resultant output.
Write Test Fixture Tear Down
Unlike TestFixtureSetup, tear down is used to de-allocate or dispose the objects. It also executes only one time
when all the tests execution ends. In our case we’ll use this method to nullify _products instance. The attribute
used for Test fixture tear down is [TestFixtureTearDown].
Following is the code for teardown.
#region TestFixture TearDown.
/// <summary>
/// TestFixture teardown
/// </summary>
[TestFixtureTearDown]
public void DisposeAllObjects()
20. {
_products = null;
}
#endregion
Note that we have till now not written any unit test.
Write Test Setup
TestFixtureSetUp is a onetime run process where as [SetUp] marked method is executed after each test.
Each test should be independent and should be tested with a fresh set of input. Setup helps us to re-initialize
data for each test. Therefore all the required initialization for tests are written in this particular method
marked with [SetUp] attribute. I have written few methods and initialized the private variables in this
method. These lines of code execute after each test ends, so that individual tests do not depend on any other
written test and do not get hampered with other tests pass or fail status. Code for Setup,
#region Setup
/// <summary>
/// Re-initializes test.
/// </summary>
[SetUp]
public void ReInitializeTest()
{
_dbEntities = new Mock<WebApiDbEntities>().Object;
_productRepository = SetUpProductRepository();
var unitOfWork = new Mock<IUnitOfWork>();
unitOfWork.SetupGet(s => s.ProductRepository).Returns(_productRepository);
_unitOfWork = unitOfWork.Object;
_productService = new ProductServices(_unitOfWork);
}
#endregion
We make use of Mock framework in this method to mock the private variable instances. Like for _dbEntities
we write _dbEntities = new Mock<WebApiDbEntities>().Object; . This means that we are mocking
WebDbEntities class and getting its proxy object. Mock class is the class from Moq framework, so include the
respective namespace using Moq; in the class
Write Test Tear down
Like test Setup runs after every test, similarly Test [TearDown] is invoked after every test execution is complete. You
can use tear down to dispose and nullify the objects that are initialized while setup. The method for tear down should be
decorated with [TearDown] attribute. Following is the test tear down implementation.
/// <summary>
/// Tears down each test data
21. /// </summary>
[TearDown]
public void DisposeTest()
{
_productService = null;
_unitOfWork = null;
_productRepository = null;
if (_dbEntities != null)
_dbEntities.Dispose();
}
Mocking Repository
I talked about mocking repository for the entities. I have created a method SetUpProductRepository() to mock
Product Repository and assign it to _productrepository in ReInitializeTest() method.
private GenericRepository<Product> SetUpProductRepository()
{
// Initialise repository
var mockRepo = new Mock<GenericRepository<Product>>(MockBehavior.Default, _dbEntities);
// Setup mocking behavior
mockRepo.Setup(p => p.GetAll()).Returns(_products);
mockRepo.Setup(p => p.GetByID(It.IsAny<int>()))
.Returns(new Func<int, Product>(
id => _products.Find(p => p.ProductId.Equals(id))));
mockRepo.Setup(p => p.Insert((It.IsAny<Product>())))
.Callback(new Action<Product>(newProduct =>
{
dynamic maxProductID = _products.Last().ProductId;
dynamic nextProductID = maxProductID + 1;
newProduct.ProductId = nextProductID;
_products.Add(newProduct);
}));
mockRepo.Setup(p => p.Update(It.IsAny<Product>()))
.Callback(new Action<Product>(prod =>
{
var oldProduct = _products.Find(a => a.ProductId == prod.ProductId);
oldProduct = prod;
}));
mockRepo.Setup(p => p.Delete(It.IsAny<Product>()))
.Callback(new Action<Product>(prod =>
{
var productToRemove =
_products.Find(a => a.ProductId == prod.ProductId);
22. if (productToRemove != null)
_products.Remove(productToRemove);
}));
// Return mock implementation object
return mockRepo.Object;
}
Here we mock all the required methods of Product Repository to get the desired data from _products object
and not from actual database.
The single line of code var mockRepo = new Mock<GenericRepository<Product>>(MockBehavior.Default,
_dbEntities);
mocks the Generic Repository for Product and mockRepo.Setup() mocks the repository methods by passing
relevant delegates to the method.
Initialize UnitOfWork and Service
I have written following lines of code in ReInitializeTest() method i.e. our setup method,
var unitOfWork = new Mock<IUnitOfWork>();
unitOfWork.SetupGet(s => s.ProductRepository).Returns(_productRepository);
_unitOfWork = unitOfWork.Object;
_productService = new ProductServices(_unitOfWork);
Here you can see that I am trying to mock the UnitOfWork instance and forcing it to perform all its transactions and
operations on _productRepository that we have mocked earlier. This means that all the transactions will be limited to
the mocked repository and actual database or actual repository will not be touched. Same goes for service as well; we
are initializing product Services with this mocked _unitOfWork. So when we use _productService in actual tests, it
actually works on mocked UnitOfWork and test data only.
23. All set now and we are ready to write unit tests for ProductService. We’ll write test to perform all the CRUD operations
that are part of ProductService.
1. GetAllProductsTest ()
Our ProductService in BusinessServices project contains a method named GetAllProducts (), following is the
implementation,
public IEnumerable<BusinessEntities.ProductEntity> GetAllProducts()
{
var products = _unitOfWork.ProductRepository.GetAll().ToList();
if (products.Any())
{
Mapper.CreateMap<Product, ProductEntity>();
var productsModel = Mapper.Map<List<Product>, List<ProductEntity>>(products);
return productsModel;
}
return null;
}
We see here, that this method fetches all the available products from the database, maps the database entity
to our custom BusinessEntities.ProductEntity and returns the list of custom BusinessEntities.ProductEntity. It
returns null if no products are found.
To start writing a test method, you need to decorate that test method with [Test] attribute of NUnit
framework. This attribute specifies that particular method is a Unit Test method.
Following is the unit test method I have written for the above mentioned business service method,
[Test]
public void GetAllProductsTest()
{
var products = _productService.GetAllProducts();
var productList =
products.Select(
productEntity =>
new Product {ProductId = productEntity.ProductId, ProductName =
productEntity.ProductName}).ToList();
var comparer = new ProductComparer();
CollectionAssert.AreEqual(
productList.OrderBy(product => product, comparer),
_products.OrderBy(product => product, comparer), comparer);
}
We used instance of _productService and called the GetAllProducts() method, that will ultimately execute on
mocked UnitOfWork and Repository to fetch test data from _products list. The products returned from the
method are of type BusinessEntities.ProductEntity and we need to compare the returned products with our
24. existing _products list i.e. the list of DataModel.Product i.e. a mocked database entity, so we need to convert
the returned BusinessEntities.ProductEntity list to DataModel.Product list. We do this with the following line
of code,
var productList =
products.Select(
productEntity =>
new Product {ProductId = productEntity.ProductId, ProductName =
productEntity.ProductName}).ToList();
Now we got two lists to compare, one _products list i.e. the actual products and another productList i.e. the
products returned from the service. I have written a helper class and compare method to convert the two
Product list in TestHelper project. This method checks the list items and compares them for equality of values.
You can add a class named ProductComparer to TestHelper project with following implementations,
public class ProductComparer : IComparer, IComparer<Product>
{
public int Compare(object expected, object actual)
{
var lhs = expected as Product;
var rhs = actual as Product;
if (lhs == null || rhs == null) throw new InvalidOperationException();
return Compare(lhs, rhs);
}
public int Compare(Product expected, Product actual)
{
int temp;
return (temp = expected.ProductId.CompareTo(actual.ProductId)) != 0 ? temp :
expected.ProductName.CompareTo(actual.ProductName);
}
}
To assert the result we use CollectionAssert.AreEqual of NUnit where we pass both the lists and
comparer.
CollectionAssert.AreEqual(
productList.OrderBy(product => product, comparer),
_products.OrderBy(product => product, comparer), comparer);
Since I have NUnit plugin in my visual studio provided by Resharper, let me debug the test method to see the
actual result of Assert. We’ll run all the tests with NUnit UI at the end of the article.
26. We got both the list, and we need to check the comparison of the lists, I just pressed F5 and got the result on TestUI as,
This shows our test is passed, i.e. the expected and returned result is same.
2. GetAllProductsTestForNull ()
You can also write the test for null check for the same method where you nullify the _products list before you
invoke the service method. We actually need to write tests that cover all the exit points of the invoked
method.
27. Following test covers another exit point of the method that returns null in case of no products found.
/// <summary>
/// Service should return null
/// </summary>
[Test]
public void GetAllProductsTestForNull()
{
_products.Clear();
var products = _productService.GetAllProducts();
Assert.Null(products);
SetUpProducts();
}
In above mentioned test, we first clear the _products list and invoke the service method. Now assert the result
for null because our expected result and actual result should be null. I called the SetUpProducts() method
again to populate the _products list, but you can do this in test setup method as well i.e. ReInitializeTest().
Now let’s move to other tests.
3. GetProductByRightIdTest ()
Here we test GetProductById() method of ProductService. Ideal behavior is that if I invoke the method with a
valid id, the method should return the valid product. Now let’s suppose I know the product id for my product
named “Mobile” and I invoke the test using that id, so ideally I should get a product with the product name
mobile.
/// <summary>
/// Service should return product if correct id is supplied
/// </summary>
[Test]
public void GetProductByRightIdTest()
{
var mobileProduct = _productService.GetProductById(2);
28. if (mobileProduct != null)
{
Mapper.CreateMap<ProductEntity, Product>();
var productModel = Mapper.Map<ProductEntity, Product>(mobileProduct);
AssertObjects.PropertyValuesAreEquals(productModel,
_products.Find(a =>
a.ProductName.Contains("Mobile")));
}
}
The above code is self-explanatory except the line AssertObjects.PropertyValuesAreEquals.
_productService.GetProductById(2); line fetches the product with product id 2.
Mapper.CreateMap<ProductEntity, Product>();
var productModel = Mapper.Map<ProductEntity, Product>(mobileProduct);
Above code maps the returned custom ProductEntity to DataModel.Product
AssertObjects is one more class I have added inside TestHelper class. The purpose of this class is to compare
the properties of two objects. This is a common generic class applicable for all type of class objects having
properties. Its method PropertyValuesAreEquals() checks for equality of the properties.
AssertObjects class:
using System.Collections;
using System.Reflection;
using NUnit.Framework;
namespace TestsHelper
{
public static class AssertObjects
{
public static void PropertyValuesAreEquals(object actual, object expected)
{
PropertyInfo[] properties = expected.GetType().GetProperties();
foreach (PropertyInfo property in properties)
{
object expectedValue = property.GetValue(expected, null);
object actualValue = property.GetValue(actual, null);
if (actualValue is IList)
AssertListsAreEquals(property, (IList)actualValue,
(IList)expectedValue);
else if (!Equals(expectedValue, actualValue))
if (property.DeclaringType != null)
Assert.Fail("Property {0}.{1} does not match. Expected: {2} but was:
{3}", property.DeclaringType.Name, property.Name, expectedValue,
actualValue);
}
}
29. private static void AssertListsAreEquals(PropertyInfo property, IList actualList,
IList expectedList)
{
if (actualList.Count != expectedList.Count)
Assert.Fail("Property {0}.{1} does not match. Expected IList containing
{2} elements but was IList containing {3} elements",
property.PropertyType.Name, property.Name, expectedList.Count,
actualList.Count);
for (int i = 0; i < actualList.Count; i++)
if (!Equals(actualList[i], expectedList[i]))
Assert.Fail("Property {0}.{1} does not match. Expected IList with element
{1} equals to {2} but was IList with element {1} equals to {3}",
property.PropertyType.Name, property.Name, expectedList[i],
actualList[i]);
}
}
}
Running the test,
4. GetProductByWrongIdTest ()
30. In this test we test the service method with wrong id and expect null in return.
/// <summary>
/// Service should return null
/// </summary>
[Test]
public void GetProductByWrongIdTest()
{
var product = _productService.GetProductById(0);
Assert.Null(product);
}
5. AddNewProductTest ()
In this unit test we test the CreateProduct() method of ProductService. Following is the unit test written for
creating a new product.
/// <summary>
/// Add new product test
/// </summary>
[Test]
public void AddNewProductTest()
{
var newProduct = new ProductEntity()
{
ProductName = "Android Phone"
};
var maxProductIDBeforeAdd = _products.Max(a => a.ProductId);
newProduct.ProductId = maxProductIDBeforeAdd + 1;
_productService.CreateProduct(newProduct);
var addedproduct = new Product() {ProductName = newProduct.ProductName, ProductId =
newProduct.ProductId};
AssertObjects.PropertyValuesAreEquals(addedproduct, _products.Last());
31. Assert.That(maxProductIDBeforeAdd + 1, Is.EqualTo(_products.Last().ProductId));
}
In above code I have created a dummy product with product name “Android Phone” and assigned the product
id as the incremented id to the maximum value of productId of the product that lies in _products list. Ideally if
my test is success, the added product should reflect in _products list as last product with maximum product id.
To verify the result, I have used two asserts, first one checks the properties of expected and actual product
and second one verifies the product id.
var addedproduct = new Product() {ProductName = newProduct.ProductName, ProductId =
newProduct.ProductId};
addedProduct is the custom product that is expected to be added in the _products list and _products.Last()
gives us last product of the list. So,
AssertObjects.PropertyValuesAreEquals(addedproduct, _products.Last()); checks for all the
properties of dummy as well as last added product and,
Assert.That(maxProductIDBeforeAdd + 1, Is.EqualTo(_products.Last().ProductId)); checks if the
last product added has the same product id as supplied while creating the product.
32. After full execution,
The test passes, that means the expected value that was product id 6 was equal to the product id of the last
added product in _products list. And we can also see that, earlier we had only 5 products in _products list and
now we have added a 6th
one.
6. UpdateProductTest ()
This is the unit test to check if the product is updated or not. This test is for UpdateProduct() method of
ProductService.
/// <summary>
/// Update product test
33. /// </summary>
[Test]
public void UpdateProductTest()
{
var firstProduct = _products.First();
firstProduct.ProductName = "Laptop updated";
var updatedProduct = new ProductEntity()
{ProductName = firstProduct.ProductName, ProductId = firstProduct.ProductId};
_productService.UpdateProduct(firstProduct.ProductId, updatedProduct);
Assert.That(firstProduct.ProductId, Is.EqualTo(1)); // hasn't changed
Assert.That(firstProduct.ProductName, Is.EqualTo("Laptop updated")); // Product name
changed
}
In this test I am trying to update first product from _products list. I have changed the product name to “Laptop
Updated” and invoked the UpdateProduct () method of ProductService. I have made two asserts to check the updated
product from _products list, one for productId and second for product name. We see that we get the updated product
while we assert.
7. DeleteProductTest ()
34. Following is the test for DeleteProduct () method in ProductService.
/// <summary>
/// Delete product test
/// </summary>
[Test]
public void DeleteProductTest()
{
int maxID = _products.Max(a => a.ProductId); // Before removal
var lastProduct = _products.Last();
// Remove last Product
_productService.DeleteProduct(lastProduct.ProductId);
Assert.That(maxID, Is.GreaterThan(_products.Max(a => a.ProductId))); // Max id
reduced by 1
}
I have written the test to verify the max id of product from the list of products. Get max id of the product,
delete the last product and check the max id of the product from the list. The prior max id should be greater
than the last product’s product id.
Max id before delete was 5 and after delete is 4 that means a product is deleted from _products list therefore
statement : Assert.That(maxID, Is.GreaterThan(_products.Max(a => a.ProductId))); passes as 5 is
greater than 4.
35. We have covered all the methods of ProductService under unit tests. Following is the final class that covers all
the tests for this service.
#region using namespaces.
using System;
using System.Collections.Generic;
using System.Linq;
using AutoMapper;
using BusinessEntities;
using DataModel;
using DataModel.GenericRepository;
using DataModel.UnitOfWork;
using Moq;
using NUnit.Framework;
using TestsHelper;
#endregion
namespace BusinessServices.Tests
{
/// <summary>
/// Product Service Test
/// </summary>
36. public class ProductServicesTest
{
#region Variables
private IProductServices _productService;
private IUnitOfWork _unitOfWork;
private List<Product> _products;
private GenericRepository<Product> _productRepository;
private WebApiDbEntities _dbEntities;
#endregion
#region Test fixture setup
/// <summary>
/// Initial setup for tests
/// </summary>
[TestFixtureSetUp]
public void Setup()
{
_products = SetUpProducts();
}
#endregion
#region Setup
/// <summary>
/// Re-initializes test.
/// </summary>
[SetUp]
public void ReInitializeTest()
{
_dbEntities = new Mock<WebApiDbEntities>().Object;
_productRepository = SetUpProductRepository();
var unitOfWork = new Mock<IUnitOfWork>();
unitOfWork.SetupGet(s => s.ProductRepository).Returns(_productRepository);
_unitOfWork = unitOfWork.Object;
_productService = new ProductServices(_unitOfWork);
}
#endregion
#region Private member methods
/// <summary>
/// Setup dummy repository
/// </summary>
/// <returns></returns>
private GenericRepository<Product> SetUpProductRepository()
{
// Initialise repository
var mockRepo = new Mock<GenericRepository<Product>>(MockBehavior.Default,
_dbEntities);
// Setup mocking behavior
mockRepo.Setup(p => p.GetAll()).Returns(_products);
37. mockRepo.Setup(p => p.GetByID(It.IsAny<int>()))
.Returns(new Func<int, Product>(
id => _products.Find(p => p.ProductId.Equals(id))));
mockRepo.Setup(p => p.Insert((It.IsAny<Product>())))
.Callback(new Action<Product>(newProduct =>
{
dynamic maxProductID = _products.Last().ProductId;
dynamic nextProductID = maxProductID + 1;
newProduct.ProductId = nextProductID;
_products.Add(newProduct);
}));
mockRepo.Setup(p => p.Update(It.IsAny<Product>()))
.Callback(new Action<Product>(prod =>
{
var oldProduct = _products.Find(a => a.ProductId == prod.ProductId);
oldProduct = prod;
}));
mockRepo.Setup(p => p.Delete(It.IsAny<Product>()))
.Callback(new Action<Product>(prod =>
{
var productToRemove =
_products.Find(a => a.ProductId == prod.ProductId);
if (productToRemove != null)
_products.Remove(productToRemove);
}));
// Return mock implementation object
return mockRepo.Object;
}
/// <summary>
/// Setup dummy products data
/// </summary>
/// <returns></returns>
private static List<Product> SetUpProducts()
{
var prodId = new int();
var products = DataInitializer.GetAllProducts();
foreach (Product prod in products)
prod.ProductId = ++prodId;
return products;
}
#endregion
#region Unit Tests
/// <summary>
/// Service should return all the products
/// </summary>
38. [Test]
public void GetAllProductsTest()
{
var products = _productService.GetAllProducts();
if (products != null)
{
var productList =
products.Select(
productEntity =>
new Product {ProductId = productEntity.ProductId, ProductName =
productEntity.ProductName}).
ToList();
var comparer = new ProductComparer();
CollectionAssert.AreEqual(
productList.OrderBy(product => product, comparer),
_products.OrderBy(product => product, comparer), comparer);
}
}
/// <summary>
/// Service should return null
/// </summary>
[Test]
public void GetAllProductsTestForNull()
{
_products.Clear();
var products = _productService.GetAllProducts();
Assert.Null(products);
SetUpProducts();
}
/// <summary>
/// Service should return product if correct id is supplied
/// </summary>
[Test]
public void GetProductByRightIdTest()
{
var mobileProduct = _productService.GetProductById(2);
if (mobileProduct != null)
{
Mapper.CreateMap<ProductEntity, Product>();
var productModel = Mapper.Map<ProductEntity, Product>(mobileProduct);
AssertObjects.PropertyValuesAreEquals(productModel,
_products.Find(a => a.ProductName.Contains("Mobile")));
}
}
/// <summary>
/// Service should return null
/// </summary>
[Test]
public void GetProductByWrongIdTest()
{
var product = _productService.GetProductById(0);
Assert.Null(product);
}
39. /// <summary>
/// Add new product test
/// </summary>
[Test]
public void AddNewProductTest()
{
var newProduct = new ProductEntity()
{
ProductName = "Android Phone"
};
var maxProductIDBeforeAdd = _products.Max(a => a.ProductId);
newProduct.ProductId = maxProductIDBeforeAdd + 1;
_productService.CreateProduct(newProduct);
var addedproduct = new Product() {ProductName = newProduct.ProductName, ProductId
= newProduct.ProductId};
AssertObjects.PropertyValuesAreEquals(addedproduct, _products.Last());
Assert.That(maxProductIDBeforeAdd + 1, Is.EqualTo(_products.Last().ProductId));
}
/// <summary>
/// Update product test
/// </summary>
[Test]
public void UpdateProductTest()
{
var firstProduct = _products.First();
firstProduct.ProductName = "Laptop updated";
var updatedProduct = new ProductEntity()
{ProductName = firstProduct.ProductName, ProductId = firstProduct.ProductId};
_productService.UpdateProduct(firstProduct.ProductId, updatedProduct);
Assert.That(firstProduct.ProductId, Is.EqualTo(1)); // hasn't changed
Assert.That(firstProduct.ProductName, Is.EqualTo("Laptop updated")); // Product
name changed
}
/// <summary>
/// Delete product test
/// </summary>
[Test]
public void DeleteProductTest()
{
int maxID = _products.Max(a => a.ProductId); // Before removal
var lastProduct = _products.Last();
// Remove last Product
_productService.DeleteProduct(lastProduct.ProductId);
Assert.That(maxID, Is.GreaterThan(_products.Max(a => a.ProductId))); // Max id
reduced by 1
}
#endregion
#region Tear Down
40. /// <summary>
/// Tears down each test data
/// </summary>
[TearDown]
public void DisposeTest()
{
_productService = null;
_unitOfWork = null;
_productRepository = null;
if (_dbEntities != null)
_dbEntities.Dispose();
}
#endregion
#region TestFixture TearDown.
/// <summary>
/// TestFixture teardown
/// </summary>
[TestFixtureTearDown]
public void DisposeAllObjects()
{
_products = null;
}
#endregion
}
}
TokenService Tests
Now that we have completed all the tests for ProductService, I am sure you must have got an idea on how to
write unit tests for methods. Note that primarily unit tests are only written to publically exposed methods
because the private methods automatically get tested through those public methods in the class. I’ll not
explain too much theory for TokenService tests and only navigate through code. I’ll explain the details
wherever necessary.
Tests Setup
Add a new class named TokenServicesTests.cs in BusinessServices.Tests project.
Declare variables
Define the private variable that we’ll use in the class to write tests,
#region Variables
private ITokenServices _tokenServices;
private IUnitOfWork _unitOfWork;
41. private List<Token> _tokens;
private GenericRepository<Token> _tokenRepository;
private WebApiDbEntities _dbEntities;
private const string SampleAuthToken = "9f907bdf-f6de-425d-be5b-b4852eb77761";
#endregion
Here _tokenService will hold mock for TokenServices, _unitOfWork for UnitOfWork class, __tokens will hold
dummy tokens from DataInitializer class of TestHelper project, _tokenRepository and _dbEntities holds mock
for Token Repository and WebAPIDbEntities from DataModel project respectively
Write Test Fixture Setup
#region Test fixture setup
/// <summary>
/// Initial setup for tests
/// </summary>
[TestFixtureSetUp]
public void Setup()
{
_tokens = SetUpTokens();
}
#endregion
SetUpTokens () method fetches tokens from DataInitializer class and not from database and assigns a unique
id to each token by iterating on them.
/// <summary>
/// Setup dummy tokens data
/// </summary>
/// <returns></returns>
private static List<Token> SetUpTokens()
{
var tokId = new int();
var tokens = DataInitializer.GetAllTokens();
foreach (Token tok in tokens)
tok.TokenId = ++tokId;
return tokens;
}
The result data is assigned to __tokens list to be used in setting up mock repository and in every individual test
for comparison of actual vs resultant output.
Write Test Fixture Tear Down
#region TestFixture TearDown.
/// <summary>
/// TestFixture teardown
/// </summary>
42. [TestFixtureTearDown]
public void DisposeAllObjects()
{
_tokens = null;
}
#endregion
Write Test Setup
#region Setup
/// <summary>
/// Re-initializes test.
/// </summary>
[SetUp]
public void ReInitializeTest()
{
_dbEntities = new Mock<WebApiDbEntities>().Object;
_tokenRepository = SetUpTokenRepository();
var unitOfWork = new Mock<IUnitOfWork>();
unitOfWork.SetupGet(s => s.TokenRepository).Returns(_tokenRepository);
_unitOfWork = unitOfWork.Object;
_tokenServices = new TokenServices(_unitOfWork);
}
#endregion
Write Test Tear down
#region Tear Down
/// <summary>
/// Tears down each test data
/// </summary>
[TearDown]
public void DisposeTest()
{
_tokenServices = null;
_unitOfWork = null;
_tokenRepository = null;
if (_dbEntities != null)
_dbEntities.Dispose();
}
#endregion
43. Mocking Repository
private GenericRepository<Token> SetUpTokenRepository()
{
// Initialise repository
var mockRepo = new Mock<GenericRepository<Token>>(MockBehavior.Default, _dbEntities);
// Setup mocking behavior
mockRepo.Setup(p => p.GetAll()).Returns(_tokens);
mockRepo.Setup(p => p.GetByID(It.IsAny<int>()))
.Returns(new Func<int, Token>(
id => _tokens.Find(p => p.TokenId.Equals(id))));
mockRepo.Setup(p => p.GetByID(It.IsAny<string>()))
.Returns(new Func<string, Token>(
authToken => _tokens.Find(p => p.AuthToken.Equals(authToken))));
mockRepo.Setup(p => p.Insert((It.IsAny<Token>())))
.Callback(new Action<Token>(newToken =>
{
dynamic maxTokenID = _tokens.Last().TokenId;
dynamic nextTokenID = maxTokenID + 1;
newToken.TokenId = nextTokenID;
_tokens.Add(newToken);
}));
mockRepo.Setup(p => p.Update(It.IsAny<Token>()))
.Callback(new Action<Token>(token =>
{
var oldToken = _tokens.Find(a => a.TokenId == token.TokenId);
oldToken = token;
}));
mockRepo.Setup(p => p.Delete(It.IsAny<Token>()))
.Callback(new Action<Token>(prod =>
{
var tokenToRemove =
_tokens.Find(a => a.TokenId == prod.TokenId);
if (tokenToRemove != null)
_tokens.Remove(tokenToRemove);
}));
//Create setup for other methods too. note non virtauls methods can not be set up
// Return mock implementation object
return mockRepo.Object;
}
Note, while mocking repository, I have setup two mocks for GetById(). There is a minor change I did in the
database, I have marked AuthToken field as a primary key too. So it may be a situation where mock gets
confused on calling the method that for which primary key the request has been made. So I have implemented
the mock both for TokenId and AuthToken field,
44. mockRepo.Setup(p => p.GetByID(It.IsAny<int>())).Returns(new Func<int, Token>(
id => _tokens.Find(p => p.TokenId.Equals(id))));
mockRepo.Setup(p => p.GetByID(It.IsAny<string>())).Returns(new Func<string, Token>(
authToken => _tokens.Find(p => p.AuthToken.Equals(authToken))));
The overall setup is of same nature as we wrote for ProductService. Let us move on to unit tests.
1. GenerateTokenByUseridTest ()
This unit test is to test the GenerateToken method of TokenServices business service. In this method a new
token is generated in the database against a user. We’ll use _tokens list for all these transactions. Currently we
have only two token entries in _tokens list generated from DataInitializer. Now when the test executes it
should expect one more token to be added to the list.
[Test]
public void GenerateTokenByUserIdTest()
{
const int userId = 1;
var maxTokenIdBeforeAdd = _tokens.Max(a => a.TokenId);
var tokenEntity = _tokenServices.GenerateToken(userId);
var newTokenDataModel = new Token()
{
AuthToken = tokenEntity.AuthToken,
TokenId = maxTokenIdBeforeAdd+1,
ExpiresOn = tokenEntity.ExpiresOn,
IssuedOn = tokenEntity.IssuedOn,
UserId = tokenEntity.UserId
};
AssertObjects.PropertyValuesAreEquals(newTokenDataModel, _tokens.Last());
}
I have taken a default user id as 1, and stored the max token id from the list of tokens. Call the service method
GenerateTokenEntity (). Since our service method returns BusinessEntities.TokenEntity, we need to map it to
new DataModel.Token object for comparison. So expected result is that all the properties of this token should
match the last token of the _token list assuming that list is updated through the test.
45. Now since all the properties of the resultant and actual object match, so our test passes.
46. 2. ValidateTokenWithRightAuthToken ()
/// <summary>
/// Validate token test
/// </summary>
[Test]
public void ValidateTokenWithRightAuthToken()
{
var authToken = Convert.ToString(SampleAuthToken);
var validationResult = _tokenServices.ValidateToken(authToken);
Assert.That(validationResult,Is.EqualTo(true));
}
This test validates AuthToken through ValidateToken method of TokenService. Ideally if correct token is
passed, the service should return true.
Here we get validationResult as true therefore test should pass.
3. ValidateTokenWithWrongAuthToken ()
47. Testing same method for its alternate exit point, therefore with wrong token, the service should return false.
[Test]
public void ValidateTokenWithWrongAuthToken()
{
var authToken = Convert.ToString("xyz");
var validationResult = _tokenServices.ValidateToken(authToken);
Assert.That(validationResult, Is.EqualTo(false));
}
Here validationResult is false, and is compared to false value, so test should ideally pass.
UserService Tests
I have tried writing unit tests for UserService as per our service implementations, but encountered an error
while mocking up our repositories Get () method that takes predicate or where condition as a parameter.
public TEntity Get(Func<TEntity, Boolean> where)
{
return DbSet.Where(where).FirstOrDefault<TEntity>();
}
Since our service methods heavily depend on the Get method, so none of the methods could be tested, but
apart from this you can search for any other mocking framework that takes care of these situations.I guess this
is a bug in mocking framework. Alternatively refrain yourself from using Get method with predicate (I would
not suggest this approach as it is against the testing strategy.Our tests should not be limited to technical
feasibility of methods). I got following error while mocking repository,
48. “Invalid setup on a non-virtual (overridable in VB)”. I have commented out all UserService Unit test code, you
can find it in available source code.
Test through NUnit UI
We have completed almost all the BusinessServices test, now let us try to execute these test on NUnit UI.
1. Step 1:
Launch NUnit UI. I have already explained how to install NUnit on the windows machine. Just launch
the NUnit interface with its launch icon,
49. 2. Step 2 :
Once the interface opens, click on File -> New Project and name the project as WebAPI.nunit and save it at any
windows location.
50.
51. 3. Step 3: Now, click on Project-> Add Assembly and browse for BusinessServices.Tests.dll (The library
created for your unit test project when compiled)
4. Step 4: Once the assembly is browsed, you’ll see all the unit tests for that test project gets loaded in
the UI and are visible on the interface.
52. 5. At the right hand side panel of the interface, you’ll see a Run button that runs all the tests of business
service. Just select the node BusinessServices in the tests tree on left side and press Run button on the
right side.
Once you run the tests, you’ll get green progress bar on right side and tick mark on all the tests on left side.
That means all the tests are passed. In case any test fails, you’ll get cross mark on the test and red progress bar
on right side.
53. But here, all of our tests are passed.
WebAPI Tests
Unit tests for WebAPI are not exactly like service methods, but vary in terms of testing HttpResponse,
returned JSON, exception responses etc. Note that we’ll mock the classes and repository in a similar way in
WebAPI unit tests as we did for services. One way of testing a web api is through web client and testing the
actual endpoint or hosted URL of the service, but that is not considered as a unit test, that is called integration
testing. In the next part of the article I’ll explain step by step procedure to unit test a web API. We’ll write tests
for Product Controller.
Conclusion
In this article we learnt how to write unit tests for core business logic and primarily on basic CURD operations.
The purpose was to get a basic idea on how unit tests are written and executed. You can add your own flavor
to this that helps you in your real time project. My next article which explains unit tests for WebAPI controllers
will be the continuation of this part. I hope this was useful to you. You can download the complete source
code of this article with packages from GitHub. Happy coding
Other Series
My other series of articles:
Introduction to MVC Architecture and Separation of Concerns: Part 1
Diving Into OOP (Day 1): Polymorphism and Inheritance (Early Binding/Compile Time Polymorphism)
For more informative articles visit my Blog.