Test Isolation and Mocking Technion – Institute of Technology 236700 Author: Gal Lalouche © 1 Author: Gal Lalouche - Technion 2016 ©

Slides:



Advertisements
Similar presentations
Written by: Dr. JJ Shepherd
Advertisements

Integration Testing When testing a module in isolation –Called modules need to be replaced –Tested module needs to be called A D ′ E ′ main driver module.
(Quickly) Testing the Tester via Path Coverage Alex Groce Oregon State University (formerly NASA/JPL Laboratory for Reliable Software)
(c) 2002 Object Mentor, Inc.1 Testing Things That Seem Hard To Test Robert Koss, Ph. D. ObjectMentor, Inc.
From Module Breakdown to Interface Specifications Completing the architectural design of Map Schematizer.
Unit Testing Tips and Tricks: Database Interaction Louis Thomas.
Mock Objects. What are Mock Objects  Any dummy object that stands in for a real object that is not available, or is difficult to use in a test case 
Programmer Testing Testing all things Java using JUnit and extensions.
Struts 2.0 an Overview ( )
Technion – Institute of Technology Author: Gal Lalouche ©
Unit Testing & Defensive Programming. F-22 Raptor Fighter.
Passing Other Objects Strings are called immutable which means that once a String object stores a value, it never changes –recall when we passed a message.
1 CSCD 330 Network Programming Lecture 13 More Client-Server Programming Sometime in 2014 Reading: References at end of Lecture.
Testing. What is Testing? Definition: exercising a program under controlled conditions and verifying the results Purpose is to detect program defects.
Monads Technion – Institute of Technology Software Design (236700) Author: Gal Lalouche - Technion 2015 © 1.
E-Learning Material Web Application Design 2. Web Application Design Use cases Guidelines Exceptions Interaction Sequence diagrams Finding objects.
CSC 213 – Large Scale Programming. Why Do We Test?
How to write the answer they’re looking for! ANSWERING APUSH ESSAY QUESTIONS.
Designing For Testability. Incorporate design features that facilitate testing Include features to: –Support test automation at all levels (unit, integration,
Capture-Replay Mocks Scandinavian Developer Conference 4 th April 2011 Geoff Bache.
DEPENDENCY INJECTION & INVERSION OF CONTROL. WHAT’S GOING TO BE COVERED Quick intro to C# for Java developers Dependency Injection Inversion of Control.
CSE 331 SOFTWARE DESIGN & IMPLEMENTATION MIDTERM REVIEW Autumn 2011.
Junit At the forefront of Test Driven Development.
Test Isolation and Mocking Technion – Institute of Technology Author: Gal Lalouche © 1 Author: Gal Lalouche - Technion 2015 ©
Dependency Injection Technion – Institute of Technology Author: Gal Lalouche - Technion 2015 ©
Best Practices. Contents Bad Practices Good Practices.
1/20/03A2-1 CS494 Interfaces and Collection in Java.
IT Just Works ©2008 BigFix, Inc. Practical Guide to Relevance Ben Kus – 1/31/2008.
 A Collection class is a data type that is capable of holding a group of items.  In Java, Collection classes can be implemented as a class, along with.
Mock Objects in Action Paulo Caroli & Sudhindra Rao Agile 2009 © ThoughtWorks 2008.
Using Mock Objects with Test Driven Development Justin Kohlhepp
Documentation. Your documentation must fit the needs of your audience. It’s always better to say one thing that is useful, as opposed to many things that.
Refactoring & Testability. Testing in OOP programming No life in flexible methodologies and for refactoring- infected developers without SOME kind of.
Mock objects.
Software testing techniques Software testing techniques Software Testability Presentation on the seminar Kaunas University of Technology.
Dependency Injection Frameworks Technion – Institute of Technology Author: Assaf Israel - Technion 2013 ©
Copyright 2007 SpringSource. Copying, publishing or distributing without express written permission is prohibited. Testing Spring Applications Unit Testing.
Mock Me If You Can An Introduction to the Mocking Framework Mockito Symposium on Software Performance 2014 Christian Wulf ― Software Engineering.
Written by: Dr. JJ Shepherd
CSE 143 Lecture 13 Recursive Backtracking slides created by Ethan Apter
CS 350 – Software Design The Adapter Pattern – Chapter 7 Gang of Four Definition: Convert the interface of a class into another interface that the client.
Author: DoanNX Time: 45’.  OOP concepts  OOP in Java.
Defensive Programming. Good programming practices that protect you from your own programming mistakes, as well as those of others – Assertions – Parameter.
Lecture IX: Testing Web Services with Mocking CS 4593 Cloud-Oriented Big Data and Software Engineering.
Dependency Injection with Guice Technion – Institute of Technology Author: Gal Lalouche - Technion 2016 ©
Beginning Software Craftsmanship Brendan Enrick Steve Smith
Winter 2006CISC121 - Prof. McLeod1 Last Time Reviewed class structure: –attributes –methods –(inner classes) Looked at the effects of the modifiers: –public.
Notices Assn 2 is due tomorrow, 7pm. Moodle quiz next week – written in the lab as before. Everything up to and including today’s lecture: Big Topics are.
Testing Technion – Institute of Technology Author: Gal Lalouche © 1 Author: Gal Lalouche - Technion 2016 ©
Today Encapsulation. Build a fully encapsulated Halloween class, going from Halloween1 to Halloween6 (eventually!): –The final version will have overloaded.
TDD Unit tests from a slightly different point of view Katie Dwyer.
Eddie Jaquith Alexis Jarvis
Test Isolation and Mocking
Designing For Testability
C++ coding standard suggestion… Separate reasoning from action, in every block. Hi, this talk is to suggest a rule (or guideline) to simplify C++ code.
CSE 374 Programming Concepts & Tools
History, Characteristics and Frameworks
Mocking Your Objects with Impunity
Test patterns.
Interpreter Pattern.
Fall 2018 CISC124 2/24/2019 CISC124 Quiz 1 marking is complete. Quiz average was about 40/60 or 67%. TAs are still grading assn 1. Assn 2 due this Friday,
Developing and testing enterprise Java applications
Making decisions with code
Designing For Testability
CMPE212 – Reminders Quiz 1 marking done. Assignment 2 due next Friday.
January 15, 2004 Adrienne Noble
CMPE212 – Reminders Assignment 2 due next Friday.
Miscellaneous Topics I
Software Specifications
Junit Tests.
Presentation transcript:

Test Isolation and Mocking Technion – Institute of Technology Author: Gal Lalouche © 1 Author: Gal Lalouche - Technion 2016 ©

Unit Testing: Isolation Initializing collaborators can include a lot of boiler plate There may be bugs in the dependencies Or dependencies may not even be written yet! I/O operations (databases/files/sockets) in test subjects may slow down tests and be hard to configure They might have nasty side effects and/or need to be cleaned up after each test Using concrete classes couples our tests with those classes 2 Author: Gal Lalouche - Technion 2016 ©

Unit Testing: Isolation Solution: Replace dependencies with mock objects Very simple dependencies that are 100% bug free Although it is possible for bugs to appear in the mock objects configurations Very easy to control their behavior Very easy to assert their use by the tested class Warehouse DataBase db ==================== void process(Order o) SQL DB db.getProduct(o.productID); Production HashTable db.getProduct(o.productID); Testing Warehouse DataBase db ==================== void process(Order o) 3 Author: Gal Lalouche - Technion 2016 ©

Unit Testing: Isolation This is another example where code testability improves its design! Isolation forces the code to be: Modular Decoupled from its dependencies More coherent Author: Gal Lalouche - Technion 2016 © 4 PizzaOrder CreditCard Processor PizzaOrder Mock Processor PizzaOrder Paypal Processor charge() Testing Today Tomorrow

Unit Testing: Mockito Problem: Writing mock objects can be a pain A great deal of time is wasted writing an object that is only used for testing Configuration can be tricky Validation is hard Case Study – Shopping cart Shoppers can add/remove items from the shopping cart Each item is a complex object with many attributes The shopping cart is initialized with a ShoppingSuggestions which offer other purchases based on the shopping cart content Author: Gal Lalouche - Technion 2016 © 5

Case study – Shopping cart Author: Gal Lalouche - Technion 2016 © 6

Case study – Shopping cart We want to test the ShoppingCart class The ShoppingSuggestions is responsible for displaying product suggestions based on the shopping cart contents Author: Gal Lalouche - Technion 2016 © 7 public class ShoppingCart { private Map items = new HashMap<>(); private ShoppingSuggestions suggestions; public ShoppingCart(ShoppingSuggestions suggestions) { this.suggestions = suggestions; } … }

Case study – Shopping cart We would like to test the following methods Author: Gal Lalouche - Technion 2016 © 8 public void addItem(Item item) { int amount = 1; if (items.containsKey(item)) { amount = items.get(item) + 1; } items.put(item, amount); suggestions.displaySuggestionFor(item); } public void removeItem(Item item) { if (!items.containsKey(item)) return; int amount = items.get(item); if (amount == 0) { items.remove(item); suggestions.removeSuggestionFor(item); return; } items.put(item, amount - 1); } Bug: Should be 1

Testing our Shopping cart – Take 1 We want to isolate the subject class and replace arguments and dependencies with controlled objects (Mocks) We will start with a naïve mock of ShoppingSuggestions We will soon see this is not enough Author: Gal Lalouche - Technion 2016 © 9 class FakeShoppingSuggestions implements ShoppingSuggestions { public boolean invoked = public void removeSuggestionFor(Item item) { invoked = true; public void displaySuggestionFor(Item item) { invoked = true; } }

Testing our Shopping cart – Take 1 Let’s look at our first test: Author: Gal Lalouche - Technion 2016 © public void updateSuggestionWhenAddingItem() { FakeShoppingSuggestions ss = new FakeShoppingSuggestions(); Item someItem = new Item(1,3000,"laptop","Lenovo”, Category.COMPUTERS ); ShoppingCart cart = new ShoppingCart(ss); cart.addItem(someItem); assertTrue(ss.invoked); } We would like to use the ShoppingSuggestions interface, so to be sure we haven’t introduced bugs in the test… but we can’t because of the last assert. We don’t really care about these details This test doesn’t check how many times each method was invoked, and is susceptible to bugs in the mock object.

Testing our Shopping cart – Take 1 Our second test is even more problematic In order to deal with some of these problems we must write smarter (and possibly buggier) mock objects. Author: Gal Lalouche - Technion 2016 © public void removeSuggestionWhenRemovingLastItem() { FakeShoppingSuggestions ss = new FakeShoppingSuggestions(); Item someItem = new Item(1,3000,"laptop","Lenovo", Category.Computers ); ShoppingCart cart = new ShoppingCart(ss); cart.addItem(someItem); ss.invoked = false; cart.removeItem(someItem); assertTrue(ss.invoked); } We must update our mocking object throughout the test. What happens if we forget?

Testing our Shopping cart – Mockito We will use a Mocking Framework (Mockito) to create our mock objects, define their behavior and verify the results. Author: Gal Lalouche - Technion 2016 © public void updateSuggestionWhenAddingItem() { ShoppingSuggestions ss = Mockito.mock(ShoppingSuggestions.class); Item someItem = Mockito.mock(Item.class); ShoppingCart cart = new ShoppingCart(ss); cart.addItem(someItem); Mockito.verify(ss, Mockito.only()).displaySuggestionFor(someItem); } We simply ask for a ShoppingSuggestions and Item mocks We can verify that the displaySuggestionFor() method will be called exactly once with the someItem argument.

Testing our Shopping cart – Take 2 Let’s look at our second test: Author: Gal Lalouche - Technion 2016 © public void removeSuggestionWhenRemovingLastItem() { ShoppingSuggestions ss = Mockito.mock(ShoppingSuggestions.class); Item someItem = Mockito.mock(Item.class); ShoppingCart cart = new ShoppingCart(ss); cart.addItem(someItem); Mockito.verify(ss, Mockito.only()).displaySuggestionFor(someItem); cart.removeItem(someItem); Mockito.verify(ss, Mockito.only()).removeSuggestionFor(someItem); } Wanted but not invoked: suggestions.removeSuggestionFor( Mock for Item, hashCode: ); -> at ShoppingCartTestWithMockito.testRemoveItem(ShoppingCartTestWithMockito.java:29)

Testing our Shopping cart – Take 2 Using a Mocking Framework we do not need to write a complete class to define the mock behavior: Author: Gal Lalouche - Technion 2016 © public void testTotalAmount() { ShoppingSuggestions ss = Mockito.mock(ShoppingSuggestions.class); Item someItem = Mockito.mock(Item.class); ShoppingCart cart = new ShoppingCart(ss); Mockito.when(someItem.getPrice()).thenReturn(70); Mockito.when(someItem.getShippingCosts()).thenReturn(6); cart.addItem(someItem); Assert.assertEquals(76, cart.total()); } We only define what we’re interested in. We can also tell the mock to throw an exception.

Mocking – Pros and Cons Pros Easy to use We don’t have to bother ourselves with configuration if we don’t want to We are truly unit testing. Our tests aren’t dependent on other classes Mocks let us design against an interface, rather than an interface Cons Mocks are still harder to use than real classes Mocks use reflection, so they are slower than Fakes or Stubs Naturally white-box testing We are deeply coupled with the class’s implementation Dependencies change => tests break => Brittle test Mocks let us test side-effects, but we should strive to make our code side-effect less Author: Gal Lalouche - Technion 2016 © 15

So What should I mock? You should mock when: You don’t want to be tied down to a single implementation Using real objects is impossible or too expensive Due to I/O, networking, side effects, concurrency, etc. But you should consider using Fakes in those cases You don’t care about initializing collaborators You don’t want to mock: Data structures For the sake of mocking; frameworks help, but mocking is still more complicated than using real objects You can’t mock final classes, methods and primitives You can use property-base testing to create random primitives and strings Food for thought: File is final, so how do we test code that uses File to access the file system? Author: Gal Lalouche - Technion 2016 © 16

Mocking – Additional Reading Mocks aren’t Stubs Quick use guide Mockito website Alternatives to Mockito: JMock, EasyMock, PowerMock (can mock final )JMockEasyMock PowerMock Author: Gal Lalouche - Technion 2016 © 17

Appendix: Verifying order Mockito offers a few gems, such as verifying the order of method invocations Author: Gal Lalouche - Technion 2016 © public void testInOrder() { ShoppingSuggestions ss = Mockito.mock(ShoppingSuggestions.class); ShoppingCart cart = new ShoppingCart(ss); Item item1 = Mockito.mock(Item.class); Item item2 = Mockito.mock(Item.class); Item item3 = Mockito.mock(Item.class); cart.addItem(item1); cart.addItem(item2); cart.addItem(item3); InOrder inOrder = Mockito.inOrder(ss); inOrder.verify(ss).displaySuggestionFor(item1); inOrder.verify(ss).displaySuggestionFor(item2); inOrder.verify(ss).displaySuggestionFor(item3); Mockito.verifyNoMoreInteractions(ss); }