By Jon Kruger. When calculating the total price of an order, add the price of the products in the order, the tax, and the shipping charges. Tax rate in.

Slides:



Advertisements
Similar presentations
AP Computer Science Anthony Keen. Computer 101 What happens when you turn a computer on? –BIOS tries to start a system loader –A system loader tries to.
Advertisements

A QA Transformation Story. History Fall 2011 Is this your developer/tester relationship?
Classes and Objects. What is Design? The parts of the software including – what information each part holds – what things each part can do – how the various.
Copyright 2008 by Pearson Education Building Java Programs Chapter 8 Lecture 8-3: Encapsulation, toString reading: self-checks: #13-18,
Class Relationships Part 1: Composition and Association CS 21a: Introduction to Computing I First Semester,
CPA: C++ Polymorphism Copyright © 2007 Mohamed Iqbal Pallipurath Overview of C++ Polymorphism Two main kinds of types in C++: native and user-defined –User-defined.
State of the Art Testability By Chad Parry. Background  The industry offers great advice on testability  Projects that follow that advice look different.
Road Map Introduction to object oriented programming. Classes
Advanced Object-Oriented Programming Features
VB Classes ISYS 573. Object-Oriented Concepts Abstraction: –To create a model of an object, for the purpose of determining the characteristics (properties)
14-Jul-15 JUnit 4. Comparing JUnit 3 to JUnit 4 All the old assertXXX methods are the same Most things are about equally easy JUnit 4 makes it easier.
Java CourseWinter 2009/10. Introduction Object oriented, imperative programming language. Developed: Inspired by C++ programming language.
Arrays and Objects OO basics. Topics Basic array syntax/use OO Vocabulary review Simple OO example Instance and Static methods Static vs. instance vs.
Inheritance. Types of Inheritance Implementation inheritance means that a type derives from a base type, taking all the base type’s member fields and.
Chapter 7 Designing Classes. Class Design When we are developing a piece of software, we want to design the software We don’t want to just sit down and.
Writing Classes (Chapter 4)
Introduction to Object Oriented Programming. Object Oriented Programming Technique used to develop programs revolving around the real world entities In.
Inheritance Joe Meehean. Object Oriented Programming Objects state (data) behavior (methods) identity (allocation of memory) Class objects definition.
Copyright 2008 by Pearson Education Building Java Programs Chapter 8 Lecture 8-2: Constructors and Encapsulation reading: self-checks: #10-17.
1 Object-Oriented Software Engineering CS Interfaces Interfaces are contracts Contracts between software groups Defines how software interacts with.
Test Driven Development Arrange, Act, Assert… Awesome Jason Offutt Software Engineer Central Christian Church
Testing in NetBeans. SWC Testing The ideal test: When the test is passed, the product is ready for delivery! Ideal – but (almost) impossible –Number of.
CS212: Object Oriented Analysis and Design Lecture 15: Inheritance in C++ -II.
E FFECTIVE C# 50 Specific Ways to Improve Your C# Second Edition Bill Wagner محمد حسین سلطانی.
Best Practices. Contents Bad Practices Good Practices.
Copyright ©2004 Virtusa Corporation | CONFIDENTIAL.Net Assignments K. R. C. Wijesinghe Trainer Virtusa Corporation.
(c) University of Washington01-1 CSC 143 Java Programming as Modeling Reading: Ch. 1-6.
Java Classes ISYS 350. Introduction to Classes A class is the blueprint for an object. – It describes a particular type of object. – It specifies the.
Topic 1 Object Oriented Programming. 1-2 Objectives To review the concepts and terminology of object-oriented programming To discuss some features of.
C# Classes and Inheritance CNS 3260 C#.NET Software Development.
Magnus
CIS162AD Inheritance Part 3 09_inheritance.ppt. CIS162AD2 Overview of Topics  Inheritance  Virtual Methods used for Overriding  Abstract Classes and.
Programming with Java © 2002 The McGraw-Hill Companies, Inc. All rights reserved. 1 McGraw-Hill/Irwin Chapter 5 Creating Classes.
More Methods and Arrays Material from Chapters 5 to 7 that we didn’t cover in 1226.
Classes. Student class We are tasked with creating a class for objects that store data about students. We first want to consider what is needed for the.
Operator Overloading Week 5.
Software Construction and Evolution - CSSE 375 Making Method Calls Simpler Shawn and Steve Below – “Be the character!” The late acting teacher Lee Strasberg.
Fall 2015CISC/CMPE320 - Prof. McLeod1 CISC/CMPE320 Today: –Review declaration, implementation, simple class structure. –Add an exception class and show.
Creating a GUI Class An example of class design using inheritance and interfaces.
Refactoring1 Improving the structure of existing code.
Topic 8Classes, Objects and Methods 1 Topic 8 l Class and Method Definitions l Information Hiding and Encapsulation l Objects and Reference Classes, Objects,
FEN 2014UCN Teknologi/act2learn1 Object-Oriented Programming “ The Three Pillars of OOP”: Encapsulation Inheritance Polymorphism The Substitution Principle.
Object Oriented Programming. OOP  The fundamental idea behind object-oriented programming is:  The real world consists of objects. Computer programs.
1 Introduction to Object Oriented Programming Chapter 10.
Topics Instance variables, set and get methods Encapsulation
Int fact (int n) { If (n == 0) return 1; else return n * fact (n – 1); } 5 void main () { Int Sum; : Sum = fact (5); : } Factorial Program Using Recursion.
1 C++ Classes & Object Oriented Programming Overview & Terminology.
INTRODUCTION TO CLASSES & OBJECTS CREATING CLASSES USING C#
Classes CS 162 (Summer 2009). Parts of a Class Instance Fields Methods.
ENCAPSULATION. WHY ENCAPSULATE? So far, the objects we have designed have all of their methods and variables visible to any part of the program that has.
Catalog of Refactoring (6) Making Method Calls Simpler.
Classes (Part 1) Lecture 3
TESTING TEST DRIVEN DEVELOPMENT
Jim Fawcett CSE681 – SW Modeling & Analysis Fall 2014
Static data members Constructors and Destructors
Classes and OOP.
Inheritance and Polymorphism
Recitation #3 Comp Semion Piskarev.
Creating and Using Classes
Subprograms and Programmer Defined Data Type
Simple Classes in C# CSCI 293 September 12, 2005.
Example: LinkedSet<T>
CS2011 Introduction to Programming I Objects and Classes
CS100J Lecture 7 Previous Lecture This Lecture Java Constructs
Overview of C++ Polymorphism
CIS 199 Final Review.
Designing For Testability
Chapter 11 Inheritance and Encapsulation and Polymorphism
CSG2H3 Object Oriented Programming
Presentation transcript:

by Jon Kruger

When calculating the total price of an order, add the price of the products in the order, the tax, and the shipping charges. Tax rate in Ohio = 7%, Michigan = 6.5%, other states = 0%. Can ship to US only. Shipping charges = $5 if cost of products is less than $25, otherwise shipping is free.

public class OrderProcessor { public decimal CalculateTotalPrice(int orderId) { // load order from database var order = Database.GetOrder(orderId); var totalPriceOfAllProducts = order.Products.Sum(p => p.Price); // calculate tax decimal tax = 0; if (order.State == "OH") tax = totalPriceOfAllProducts *.07m; else if (order.State == "MI") tax = totalPriceOfAllProducts *.065m; // calculate shipping decimal shippingCharges = 0; if (totalPriceOfAllProducts < 25) shippingCharges = 5; return totalPriceOfAllProducts + tax + shippingCharges; }

[TestFixture] public class OrderProcessorTests { private decimal _totalPrice; private Order _order; [Test] public void CalculateTotalPrice() { Given_an_order(); When_calculating_the_total_price_of_an_order(); Then_the_total_price_of_the_order_should_be(15.70m); } [TearDown] public void Cleanup() { Database.DeleteOrder(_order); } private void Given_an_order() { _order = new Order { Id = 1, State = "OH", Products = new List { new Product {Price = 10} } }; Database.SaveOrder(_order); } private When_calculating_the_total_price_of_an_order() { _totalPrice = new OrderProcessor().CalculateTotalPrice(1); } private Then_the_total_price_of_the_order_should_be(decimal amount) { _totalPrice.ShouldEqual(amount); }

We have to account for the following scenarios when writing our tests: Tax (51 possibilities) Orders can be shipped to 51 states (50 states + DC) Shipping (3 possibilities) Order total is < 25 Order total is 25 exactly Order total is > 25 Loading Order from the database (1 possibility) Return the sum of products, tax, and shipping (1 possibility) This means that we have 153 different combinations to test!

What if we tested each individual piece of the order total calculating process in isolation? Test tax calculation in each state (51 tests) Test shipping calculation (3 tests) Test that Order can be loaded from the database (1 test) Test that return value is price of products + tax + shipping (1 test) Now were down to 56 test cases from 153 test cases!

public class OrderProcessor { public decimal CalculateTotalPrice(int orderId) { // load order from database var order = Database.GetOrder(orderId); var totalPriceOfAllProducts = order.Products.Sum(p => p.Price); // calculate tax decimal tax = new TaxCalculator().CalculateTax(order); // calculate shipping decimal shippingCharges = new ShippingCalculator().CalculateShipping(order); return totalPriceOfAllProducts + tax + shippingCharges; }

public class OrderProcessor { private readonly TaxCalculator _taxCalculator; private readonly ShippingCalculator _shippingCalculator; public OrderProcessor(TaxCalculator taxCalculator, ShippingCalculator shippingCalculator) { _taxCalculator = taxCalculator; _shippingCalculator = shippingCalculator; } public decimal CalculateTotalPrice(int orderId) { // load order from database var order = Database.GetOrder(orderId); var totalPriceOfAllProducts = order.TotalPriceOfAllProducts; // calculate tax decimal tax = _taxCalculator.CalculateTax(order); // calculate shipping decimal shippingCharges = _shippingCalculator.CalculateShipping(order); return totalPriceOfAllProducts + tax + shippingCharges; } Now maybe I could create test classes that derive from TaxCalculator and ShippingCalculator…

public class OrderProcessor { private readonly ITaxCalculator _taxCalculator; private readonly IShippingCalculator _shippingCalculator; public OrderProcessor(ITaxCalculator taxCalculator, IShippingCalculator shippingCalculator) { _taxCalculator = taxCalculator; _shippingCalculator = shippingCalculator; } public decimal CalculateTotalPrice(int orderId) { // load order from database var order = Database.GetOrder(orderId); var totalPriceOfAllProducts = order.TotalPriceOfAllProducts; // calculate tax decimal tax = _taxCalculator.CalculateTax(order); // calculate shipping decimal shippingCharges = _shippingCalculator.CalculateShipping(order); return totalPriceOfAllProducts + tax + shippingCharges; } Now I dont have to worry about whether those dependencies have virtual methods.

public class OrderProcessor { private readonly ITaxCalculator _taxCalculator; private readonly IShippingCalculator _shippingCalculator; public OrderProcessor(ITaxCalculator taxCalculator, IShippingCalculator shippingCalculator) { _taxCalculator = taxCalculator; _shippingCalculator = shippingCalculator; } public decimal CalculateTotalPrice(int orderId) { // load order from database var order = Database.GetOrder(orderId); var totalPriceOfAllProducts = order.TotalPriceOfAllProducts; // calculate tax decimal tax = _taxCalculator.CalculateTax(order); // calculate shipping decimal shippingCharges = _shippingCalculator.CalculateShipping(order); return totalPriceOfAllProducts + tax + shippingCharges; } I still cant stub out the database access… I cant take a static class in as a constructor parameter!

public class OrderProcessor { private readonly IGetObjectService _getOrderService; private readonly ITaxCalculator _taxCalculator; private readonly IShippingCalculator _shippingCalculator; public OrderProcessor(IGetObjectService getOrderService, ITaxCalculator taxCalculator, IShippingCalculator shippingCalculator) { _getOrderService = getOrderService; _taxCalculator = taxCalculator; _shippingCalculator = shippingCalculator; } public decimal CalculateTotalPrice(int orderId) { // load order from database var order = _getOrderService.Get(orderId); var totalPriceOfAllProducts = order.TotalPriceOfAllProducts; // calculate tax decimal tax = _taxCalculator.CalculateTax(order); // calculate shipping decimal shippingCharges = _shippingCalculator.CalculateShipping(order); return totalPriceOfAllProducts + tax + shippingCharges; } I removed the static class and replaced it with a non-static class hidden behind an interface.

Testable code is code that can we can test using a unit test instead of an integration test Provides a way to substitute fake objects for classes that the class that were testing depends on Consistent results on every test run Manual configuration is not needed before test run Order of tests do not matter Must be able to run only some of the tests Tests must run fast

The Law of Demeter states that a method of an object may only call methods of: 1) The object itself. 2) An argument of the method. 3) Any object created within the method. 4) Any direct properties/fields of the object.

public class OrderDisplayService { private readonly IOrderProcessor _orderProcessor; public OrderDisplayService(IOrderProcessor orderProcessor) { _orderProcessor = orderProcessor; } public void ShowOrderDetails(Order order) { if (!_orderProcessor.UserAuthenticationService.IsAuthenticated) { throw new InvalidOperationException( "not logged in"); } // do more stuff } Stubbing IsAuthenticated in a test would be difficult.

public class OrderDisplayService { private readonly IOrderProcessor _orderProcessor; public OrderDisplayService(IOrderProcessor orderProcessor) { _orderProcessor = orderProcessor; } public void ShowOrderDetails(Order order) { if (!_orderProcessor.IsAuthenticated) { throw new InvalidOperationException( "not logged in"); } // do more stuff } Encapsulate IsAuthenticated inside IOrderProcessor.

public class OrderDisplayService { private IOrderProcessor _orderProcessor; private IUserAuthenticationService _userAuthenticationService; public OrderDisplayService(IOrderProcessor orderProcessor, IUserAuthenticationService userAuthenticationService) { _orderProcessor = orderProcessor; _userAuthenticationService = userAuthenticationService; } public void ShowOrderDetails(Order order) { if (!_userAuthenticationService.IsAuthenticated) { throw new InvalidOperationException( "not logged in"); } // do more stuff }

Dont new up dependencies Dont do real work in constructors Dont expose static anything Dont expose singletons Entity objects should not have external dependencies Follow the Law of Demeter