Lecture IX: Testing Web Services with Mocking CS 4593 Cloud-Oriented Big Data and Software Engineering
2 Web Service Testing Challenges Mocking Frameworks Budget-Oriented Testing
3 Challenges Web Dependencies Network Budget Instable Return Values of Services Error Conditions
4 Double Dependencies Solution: Double it! Double: highly trained replacement, vaguely resembling the actor No need to be a good actor May require different skills for different cases
5 Types of test doubles Dummies Test stubs Fake objects Mock objects
6 Dummies Simplest test double No behavior, just serve as an argument Null can be viewed as a simple double Example public class Order{ private Shop sp; public Order (Shop sp){ this.sp = sp; } public Shop getShop(){ return sp; } … } public class ShopDummy extends Shop{... } public class public void testInit(){ Order o = new order(new ShopDummy());... }
When to use dummies SUT does not invoke any method on the dependency The dependency class is an interface or abstract class with no implementation or The dependency class is hard to initialize so that you can put the initialization in the dummy once E.g., Shop sp = new Shop(new A(…), new B(…), new C(…), new D(…), new E(…)); Can put the whole thing in ShopDummy
8 Test Stubs More powerful than dummies Provide a fix value or fixed behavior for a certain method invocation Example: Always return 0 for a integer method Do nothing for a void method
9 Hard-coded Test Stubs The value or behavior is hard coded in the Stub Class public class public void test(){ Order o = new order(new ShopStub()); o.add(1122, 3);... AssertEquals(expect, o.getTotal()); o.save(); } public class ShopStub extends Shop{ public void save(Order o){ } public double getShopDiscount(){ return 0.9; }
10 Configurable Test Stubs You may set different values for different test cases public class ShopStub extends Shop{ private Exception saveExc; private discount; public setException(Exception e){ this.saveExc = e; } public setDicount(Float f){ this.discount = f; } public void save(Order o){ if(this.saveExc!=null){throw saveExc;} } public double getShopDiscount(){ return this.discount; } public class public void testAbnormalDiscount(){ ShopStub stub = new ShopStub(); stub.setDiscount(1.1); Order o = new order(stub); o.add(1122, 3);... AssertEquals(expect, o.getTotal()); o.save(); }
Fake Objects More powerful than stubs A simplified implementation of the DOC Example: a data table to fake a database Example: use a greed algorithm to fake a complex optimized algorithm Guidelines Slow -> Fast Complex -> Simple
Fake Objects Tips for fake objects As simple as possible (as long as not too time-consuming) Go to a higher level if some object is hard to fake Example: URLStatus sts = HttpConnection.open(" if(sts.status == 200){ return sts.data; }else{ return “Error”; } Need to double 1.Difficult to reproduce 2.Maybe slow 3.Affected by lots of factors
Fake Objects Example (1) Fake HttpConnection We need to fake URLStatus also public class FakeUrlStatus{ public FakeUrlStatus(int status, string data){...}; public int getStatus(){...}; public String getData(){...}; } public class FakeDropBoxApi{ private files = { }; public FakeUrlStatus read(fname){ if(files.contain(fname)){ return FakeUrlStatus(200, files[fname]); }else{ return FakeUrlStatus(-1, "Error"); } FakeURLStatus sts = FakeDropBoxApi.read("myfile"); if(sts.status == 200){ …
Fake Objects Example (2) Fake the HttpConnection + URLStatus public class FakeDropBoxHigherApi{ private files = { }; public String read(fname){ if(files.contain(fname)){ return files[fname]; }else{ return "Error"; } return FakeDropBoxHigherApi.read("myfile");
Fake Objects Choose a reasonable abstraction level to do the faking Do not need to fake lots of dependencies (put them in one box) Write simpler code (less potential bugs)
16 Mock objects Mock objects is not similar to any of the above For the ability to imitate DOC, it is similar to configurable stubs But it does some different things Mock objects do behavior-based testing Usually we only check return values or status AssertEquals (expected, actual); AssertEquals (expected, array.length); Can we do something like this? Why? Assert ( testObject.f1 calls DOC.f)
17 Mock objects Go back to the order example 17 public class public void test(){ Order o = new order(new ShopStub()); o.add(1122, 3);... AssertEquals(expect, o.getTotal()); o.save(); } public class ShopStub extends Shop{ public void save(Order o){ } public double getShopDiscount(){ return 0.9; } Problems???
Mock objects Do behavioral assertions for SUT Only cares about whether the unit to be tested is correct Do not care about the correctness of DOC Test Code SUT DOC DON’T CARE!!
Mock objects Example public void testOrder() { //initialize Shop sp = EasyMock.CreateMock(Shop.class); Order o = new Order(sp); o.add(1234, 1); o.add(4321, 3); //record EasyMock.expect(sp.getDiscount()).andReturn(0.9); EasyMock.expect(sp.save(o)); //replay EasyMock.replay(sp); AssertEquals(expect, o.getTotal()); o.Save(); EasyMock.verify(sp) }
20 Mock objects Procedure I am a mock object, just generated Record: What I am expected to be invoked, and what should I return Expect Methods Replay: See how SUT invoked me SUT Verification Results
21 Verification Verifies whether the expected methods are actually invoked Exception: missing, expected save(0xaaaa) Verifies whether the expected methods are invoked in an expected way Exception: save(null) expected save(0xaaaa)
22 Richer ways to do expectation Different frameworks support it in different ways Easymock: isA: ignore the value of argument EasyMock.expect(sp.save(isA(Order.class))) Find: expect the argument to contain a certain substring EasyMock.expect(mock.call(find(“pattern”))) Geq: expect a number larger than the given value EasyMock.expect(mock.call(Geq(1000)))
23 Orders of expected method calls Different frameworks support it in different ways Easymock Order is not checked by default createStrictMock to check order Mockito Order is not checked by default Create a InOrder object at the verification phase and add the expected invocations that should happen in order jMock More complex order control
24 Fluent Mocking Record phase: Read expectation as specifications Instead of directly generating code, the mock object generates an internal presentation, e.g. Automaton Replay phase: Check the real invocations with the internal presentation
25 Fluent Mocking: jMock
26 Types of test doubles Dummies Simplest, only for arguments Test stubs Return fixed value Can be configurable at runtime Fake objects A simplified implementation Mock objects Similar to configurable stubs Behavior checking Automatic framework support
27 Budget Oriented Testing Use test doubles for web services in unit testing and initial system testing Generating different test doubles according to the specification of the web service, consider Service Failures Error Results Empty Results Special Characters
28 Budget Oriented Testing In system testing Always record web service queries for debugging Always record web service return values for debugging purposes In performance testing Do not direct use web service for performance testing Generate a fake server to simulate the potential lags and errors in service