Mocking Unit Testing Methods with External Dependencies SoftUni Team Technical Trainers Software University

Slides:



Advertisements
Similar presentations
Software Quality Assurance QA Engineering, Testing, Bug Tracking, Test Automation Software University Technical Trainers SoftUni Team.
Advertisements

 Dimitar Ivanov Introduction to programming with microcontrollers.
C# Advanced Topics Methods, Classes and Objects SoftUni Team Technical Trainers Software University
AngularJS Routing Routes, Route Parameters, Templates, Location, Navigation SoftUni Team Technical Trainers Software University
AngularJS Services Built-in and Custom Services SoftUni Team Technical Trainers Software University
Methods Writing and using methods, overloads, ref, out SoftUni Team Technical Trainers Software University
Software University Curriculum, Courses, Exams, Jobs SoftUni Team Technical Trainers Software University
Unit Testing and Mocking
Fundamentals SoftUni Welcome to Software University SoftUni Team Technical Trainers Software University
Advanced JavaScript Course Introduction SoftUni Team Technical Trainers Software University
Project Tracking Tools Trello, Asana, Basecamp, GitHub Issue Tracker, TRAC SoftUni Team Technical Trainers Software University
AngularJS Directives Defining Custom Directives SoftUni Team Technical Trainers Software University
Software Testing Lifecycle Exit Criteria Evaluation, Continuous Integration Ivan Yonkov Technical Trainer Software University.
Teamwork and Personal Skills Course Introduction Software University SoftUni Team Technical Trainers.
Fundamentals SoftUni Welcome to Software University SoftUni Team Technical Trainers Software University
Design Patterns: Structural Design Patterns
High-Quality Programming Code Code Correctness, Readability, Maintainability, Testability, Etc. SoftUni Team Technical Trainers Software University
JavaScript Design Patterns Private Fields, Module, Revealing Module, Revealing Prototype, … Software University Technical Trainers SoftUni.
Conditional Statements Implementing Control-Flow Logic in C# SoftUni Team Technical Trainers Software University
Consuming REST Services from C# SoftUni Team Technical Trainers Software University
Loops Repeating Code Multiple Times SoftUni Team Technical Trainers Software University
Database APIs and Wrappers
Methods, Arrays, Lists, Dictionaries, Strings, Classes and Objects
Svetlin Nakov Technical Trainer Software University
Build Processes and Continuous Integration Automating Build Processes Software University Technical Trainers SoftUni Team.
SOLID Principles in Software Design
Processing Redis with.NET How to Operate with Redis Databases SoftUni Team Technical Trainers Software University
Project Tracking Tools Trello, Asana, Basecamp, GitHub Issue Tracker, TRAC Angel Georgiev Part-time Trainer Software University
Test-Driven Development Learn the "Test First" Approach to Coding SoftUni Team Technical Trainers Software University
Defining Classes Classes, Fields, Constructors, Methods, Properties SoftUni Team Technical Trainers Software University
Controllers and Markup Controllers, $scope, Markup, Directives, Expressions, Binding, Filters, Validation SoftUni Team Technical Trainers Software University.
AMD and RequireJS Splitting JavaScript Code into Dependent Modules Software University Technical Trainers SoftUni Team.
Asynchronous Web Services Writing Asynchronous Web Services SoftUni Team Technical Trainers Software University
Jekyll Static Site Generator Template-Based Site Generation Svetlin Nakov Technical Trainer Software University
JavaScript Modules and Patterns Private Fields, Module, Revealing Module, Revealing Prototype, … Software University Technical Trainers.
Responsive Design Design that Adapts to Different Devices SoftUni Team Technical Trainers Software University
Exam Preparation Algorithms Course: Sample Exam SoftUni Team Technical Trainers Software University
High-Quality Programming Code Code Correctness, Readability, Maintainability Svetlin Nakov Technical Trainer Software University
High-Quality Code: Course Introduction Course Introduction SoftUni Team Technical Trainers Software University
Design Patterns: Structural Design Patterns General and reusable solutions to common problems in software design Software University
SOLID Principles in Software Design
Advanced C# Course Introduction SoftUni Team Technical Trainers Software University
Events Event Handling in JavaScript SoftUni Team Technical Trainers Software University
Object-Oriented Programming Course Introduction Svetlin Nakov Technical Trainer Software University
Reflection Programming under the hood SoftUni Team Technical Trainers Software University
Mocking with Moq Tools for Easier Unit Testing SoftUni Team Technical Trainers Software University
Design Patterns: Behavioral Design Patterns General and reusable solutions to common problems in software design Software University
Code Formatting Formatting the Source Code Correctly SoftUni Team Technical Trainers Software University
Mocking with Moq Mocking tools for easier unit testing Svetlin Nakov Technical Trainer Software University
Test-Driven Development Learn the "Test First" Approach to Coding Svetlin Nakov Technical Trainer Software University
Programming for Beginners Course Introduction SoftUni Team Technical Trainers Software University
Sets, Dictionaries SoftUni Team Technical Trainers Software University
High-Quality Code: Course Introduction Course Introduction SoftUni Team Technical Trainers Software University
Advanced Tree Structures Binary Trees, AVL Tree, Red-Black Tree, B-Trees, Heaps SoftUni Team Technical Trainers Software University
Functional Programming Data Aggregation and Nested Queries Ivan Yonkov Technical Trainer Software University
Programming Fundamentals Course Introduction SoftUni Team Technical Trainers Software University
Doctrine The PHP ORM SoftUni Team Technical Trainers Software University
Creating Content Defining Topic, Creating Technical Training Materials SoftUni Team Technical Trainers Software University
ASP.NET MVC Course Program, Trainers, Evaluation, Exams, Resources SoftUni Team Technical Trainers Software University
Inheritance Class Hierarchies SoftUni Team Technical Trainers Software University
Advanced JavaScript Course Introduction SoftUni Team Technical Trainers Software University
Stacks and Queues Processing Sequences of Elements SoftUni Team Technical Trainers Software University
Generics SoftUni Team Technical Trainers Software University
C# OOP Advanced Course Introduction SoftUni Team Technical Trainers Software University
Java OOP Advanced Course Introduction SoftUni Team Technical Trainers Software University
High-Quality Programming Code Code Correctness, Readability, Maintainability, Testability, Etc. SoftUni Team Technical Trainers Software University
Interface Segregation / Dependency Inversion
Mocking tools for easier unit testing
Mocking Tool for easier unit testing
Best practices and architecture
Presentation transcript:

Mocking Unit Testing Methods with External Dependencies SoftUni Team Technical Trainers Software University

2  What is Mocking?  Testing Code with External Dependencies  Inversion of Control Principle  Dependency Injection  Mocking Frameworks  Using Moq Table of Contents

Testable Code

4  Goal: decoupling between modules through abstractions  Programming through interfaces DIP – Dependency Inversion Principle "Dependency Inversion Principle says that high-level modules should not depend on low-level modules. Both should depend on abstractions." "Abstractions should not depend on details. Details should depend on abstractions." Agile Principles, Patterns, and Practices in C#

5  Inversion of Control Pattern  Decouples the execution of a certain task from implementation  Every module can focus on what it is designed for  Modules make no assumptions about what other systems do but rely on their contracts  Replacing modules has no side effect on other modules  More info at How to Write Testable Code

6  How it should be?  Classes should declare what they need  Constructors should require dependencies  Dependencies should be abstractions  How to do it  Dependency Injection (DI)  The Hollywood principle "Don't call us, we'll call you!" Depend on Abstractions

7  Dependency Injection  Dependencies are passed through constructors  Pros  Classes self-documenting requirements  Works well without container  Always valid state  Cons  Many parameters  Some methods may not need everything Dependency Inversion Principle: How?

8 Constructor Injection – Example public class Copy { private IReader reader; private IReader reader; private IWriter writer; private IWriter writer; public Copy(IReader reader, IWriter writer) public Copy(IReader reader, IWriter writer) { this.reader = reader; this.reader = reader; this.writer = writer; this.writer = writer; } // Read / write data through the reader / writer // Read / write data through the reader / writer} var copy = new Copy(new ConsoleReader(), new FileWriter("out.txt"));

Mocking

10  Mocking allows unit testing code with dependencies  Class / method needs to have its dependencies isolated through abstractions  We then pass fake (mocked) dependencies and assert if the tested piece of code has correct behavior  Very helpful technique in data-driven applications where data can be different in every test run Mocking

11  ExtractImageUrls cannot be reliably tested  Accessing external data can return different results Testing Data-Driven Applications public class Crawler { public IEnumerable ExtractImageUrls( public IEnumerable ExtractImageUrls( string pageUrl) string pageUrl) { var client = new WebClient(); var client = new WebClient(); var html = client.DownloadString(pageUrl); var html = client.DownloadString(pageUrl); return this.ParseImages(html); return this.ParseImages(html); } private IEnumerable ParseImages( private IEnumerable ParseImages( string html) {... } string html) {... }} Dependency

12 1.Extract said dependency in an interface 2.Class should receive the interface through dependency injection 3.Create a mock of the dependency with static behavior (i.e. always returning same data) 4.Pass mock object to the tested class 5.Assert if tested class behavior is correct How to Test a Unit with a Dependency?

13  Create dependency interface  Create a class and implement the interface Testing a Unit with Dependencies public interface IHtmlProvider { string DownloadHtml(string pageUrl); string DownloadHtml(string pageUrl);} public class HtmlProvider : IHtmlProvider { public string DownloadHtml(string pageUrl) public string DownloadHtml(string pageUrl) { var client = new WebClient(); var client = new WebClient(); return client.DownloadString(pageUrl); return client.DownloadString(pageUrl); }} Extract dependency code into the class

14  In the tests project, set up a fake object Testing a Unit with Dependencies (3) public class FakeHtmlProvider : IHtmlProvider { public string DownloadHtml(string pageUrl) public string DownloadHtml(string pageUrl) { string fakeHtml = " " + string fakeHtml = " " + " " + " " + " Hello " + " Hello " + " " + " " + " "; " "; return fakeHtml; return fakeHtml; }} Fake IHtmlProvider whose DownloadHtml() method always returns the same string

15  Pass the fake object in the tests to the test class constructor Testing a Unit with Dependencies (4) [TestMethod] public void ExtractImageUrls_ShouldReturnCollectionOfPageImageUrls() { var fakeHtmlProvider = new FakeHtmlProvider(); var fakeHtmlProvider = new FakeHtmlProvider(); var crawler = new Crawler(fakeHtmlProvider); var crawler = new Crawler(fakeHtmlProvider); var imageUrls = crawler.ExtractImageUrls(string.Empty) var imageUrls = crawler.ExtractImageUrls(string.Empty).OrderBy(url => url).ToList();.OrderBy(url => url).ToList(); var expectedResults = new [] { var expectedResults = new [] {"nakov.png", "courses/inner/background.jpeg" }; CollectionAssert.AreEqual(expectedResults, imageUrls); CollectionAssert.AreEqual(expectedResults, imageUrls);}

Mocking Exercises in Class

Mocking Live Demo

Moq Mocking Framework

 Moq (pronounced "Mock You") is an open-source mocking framework  Facilitates the mocking process by providing an API for creating fake objects (mocks)  No need to create fake classes for every possible test scenario  Can mock almost any type, not just interfaces  E.g. Random, DateTime, etc. Moq

20  The most often used APIs:  Setup() – overrides the behavior of a specified method  Callback() – takes a callback to be executed as a result of a call to the overridden method  Returns() – specifies what the overridden method should return  Throws() – specifies what exception the overridden method should throw  It.Is () – sets constraints on overridden method parameters Moq – API methods

21 Unit Testing with Moq – Example [TestMethod] public void ExtractImageUrls_ShouldReturnCollectionOfPageImageUrls() { var mock = new Mock (); var mock = new Mock (); mock.Setup(p => p.DownloadHtml(It.IsAny ())) mock.Setup(p => p.DownloadHtml(It.IsAny ())).Returns("... ");.Returns("... "); var crawler = new Crawler(mock.HtmlProvider); var crawler = new Crawler(mock.HtmlProvider); var imageUrls = crawler.ExtractImageUrls(string.Empty) var imageUrls = crawler.ExtractImageUrls(string.Empty).OrderBy(url => url).ToList();.OrderBy(url => url).ToList(); var expectedResults = new [] { var expectedResults = new [] {"nakov.png", "courses/inner/background.jpeg" }; CollectionAssert.AreEqual(expectedResults, imageUrls); CollectionAssert.AreEqual(expectedResults, imageUrls);}

22 1.Follow the Inversion of Control pattern to provide external dependencies 2.Use mocking when your code has external dependencies  A buggy dependence may cause correct code to fail a unit test 3.Controversial points  Injecting dependencies vs. mocking  Mocking absolutely all dependencies Summary

? ? ? ? ? ? ? ? ? Mocking

License  This course (slides, examples, demos, videos, homework, etc.) is licensed under the "Creative Commons Attribution- NonCommercial-ShareAlike 4.0 International" licenseCreative Commons Attribution- NonCommercial-ShareAlike 4.0 International 24  Attribution: this work may contain portions from  "Fundamentals of Computer Programming with C#" book by Svetlin Nakov & Co. under CC-BY-SA licenseFundamentals of Computer Programming with C#CC-BY-SA  "High Quality Code" course by Telerik Academy under CC-BY-NC-SA licenseHigh Quality CodeCC-BY-NC-SA

Free Software University  Software University Foundation – softuni.orgsoftuni.org  Software University – High-Quality Education, Profession and Job for Software Developers  softuni.bg softuni.bg  Software Facebook  facebook.com/SoftwareUniversity facebook.com/SoftwareUniversity  Software YouTube  youtube.com/SoftwareUniversity youtube.com/SoftwareUniversity  Software University Forums – forum.softuni.bgforum.softuni.bg