Upgrade to Pro — share decks privately, control downloads, hide ads and more …

2014 Graduate Bootcamp: More TDD

2014 Graduate Bootcamp: More TDD

Mocks & stubs; acceptance test frameworks; web app testing

Kerry Buckley

October 28, 2014
Tweet

More Decks by Kerry Buckley

Other Decks in Programming

Transcript

  1. TDD

  2. TDD

  3. TDD

  4. A stub simply returns canned values (which may be real

    value objects or other test doubles)
  5. Identify responsibilities Does the class have a single responsibility? Yes

    test drive behaviour as normal No identify collaborating roles (interfaces) specify interactions using test doubles
  6. Implement collaborators For each role identified at the layer above…

    Identify responsibilities Does the class have a single responsibility? Yes test drive behaviour as normal No identify collaborating roles (interfaces) specify interactions using test doubles
  7. Rules* A class can arrange collaborators or do work Stub

    queries; mock commands Doubles can return value objects or other doubles (but not objects with behaviour)
  8. Rules* A class can arrange collaborators or do work Stub

    queries; mock commands Doubles can return value objects or other doubles (but not objects with behaviour) Don’t stub or mock value objects or primitives
  9. Rules* A class can arrange collaborators or do work Stub

    queries; mock commands Doubles can return value objects or other doubles (but not objects with behaviour) Don’t stub or mock value objects or primitives Don’t stub or mock the object under test
  10. Rules* A class can arrange collaborators or do work Stub

    queries; mock commands Doubles can return value objects or other doubles (but not objects with behaviour) Don’t stub or mock value objects or primitives Don’t stub or mock the object under test
  11. Rules* A class can arrange collaborators or do work Stub

    queries; mock commands Doubles can return value objects or other doubles (but not objects with behaviour) Don’t stub or mock value objects or primitives Don’t stub or mock the object under test *more what you’d call ‘guidelines’ than actual rules
  12. public class Authenticator { public Authenticator(final Repository repository) { }

    public void authenticate(String username, Session session) { } }
  13. public class Authenticator { public Authenticator(final Repository repository) { }

    public void authenticate(String username, Session session) { } } public interface Repository { User findUser(String username); }
  14. public class Authenticator { public Authenticator(final Repository repository) { }

    public void authenticate(String username, Session session) { } } public interface Repository { User findUser(String username); } public interface Session { void setUser(User user); }
  15. public class Authenticator { public Authenticator(final Repository repository) { }

    public void authenticate(String username, Session session) { } } public interface Repository { User findUser(String username); } public interface Session { void setUser(User user); } public class User { }
  16. import org.junit.Test; import static org.easymock.EasyMock.*; public class AuthenticatorTest { @Test

    public void testAuthenticate() { User user = new User(); Repository stubRepository = createMock(Repository.class); expect(stubRepository.findUser("bob")).andStubReturn(user); replay(stubRepository); Session mockSession = createMock(Session.class); mockSession.setUser(user); replay(mockSession); Authenticator authenticator = new Authenticator(stubRepository); authenticator.authenticate("bob", mockSession); verify(mockSession); } }
  17. import org.junit.Test; import static org.easymock.EasyMock.*; public class AuthenticatorTest { @Test

    public void testAuthenticate() { User user = new User(); Repository stubRepository = createMock(Repository.class); expect(stubRepository.findUser("bob")).andStubReturn(user); replay(stubRepository); Session mockSession = createMock(Session.class); mockSession.setUser(user); replay(mockSession); Authenticator authenticator = new Authenticator(stubRepository); authenticator.authenticate("bob", mockSession); verify(mockSession); } }
  18. import org.junit.Test; import static org.easymock.EasyMock.*; public class AuthenticatorTest { @Test

    public void testAuthenticate() { User user = new User(); Repository stubRepository = createMock(Repository.class); expect(stubRepository.findUser("bob")).andStubReturn(user); replay(stubRepository); Session mockSession = createMock(Session.class); mockSession.setUser(user); replay(mockSession); Authenticator authenticator = new Authenticator(stubRepository); authenticator.authenticate("bob", mockSession); verify(mockSession); } }
  19. import org.junit.Test; import static org.easymock.EasyMock.*; public class AuthenticatorTest { @Test

    public void testAuthenticate() { User user = new User(); Repository stubRepository = createMock(Repository.class); expect(stubRepository.findUser("bob")).andStubReturn(user); replay(stubRepository); Session mockSession = createMock(Session.class); mockSession.setUser(user); replay(mockSession); Authenticator authenticator = new Authenticator(stubRepository); authenticator.authenticate("bob", mockSession); verify(mockSession); } }
  20. import org.junit.Test; import static org.easymock.EasyMock.*; public class AuthenticatorTest { @Test

    public void testAuthenticate() { User user = new User(); Repository stubRepository = createMock(Repository.class); expect(stubRepository.findUser("bob")).andStubReturn(user); replay(stubRepository); Session mockSession = createMock(Session.class); mockSession.setUser(user); replay(mockSession); Authenticator authenticator = new Authenticator(stubRepository); authenticator.authenticate("bob", mockSession); verify(mockSession); } }
  21. import org.junit.Test; import static org.easymock.EasyMock.*; public class AuthenticatorTest { @Test

    public void testAuthenticate() { User user = new User(); Repository stubRepository = createMock(Repository.class); expect(stubRepository.findUser("bob")).andStubReturn(user); replay(stubRepository); Session mockSession = createMock(Session.class); mockSession.setUser(user); replay(mockSession); Authenticator authenticator = new Authenticator(stubRepository); authenticator.authenticate("bob", mockSession); verify(mockSession); } }
  22. import org.junit.Test; import static org.easymock.EasyMock.*; public class AuthenticatorTest { @Test

    public void testAuthenticate() { User user = new User(); Repository stubRepository = createMock(Repository.class); expect(stubRepository.findUser("bob")).andStubReturn(user); replay(stubRepository); Session mockSession = createMock(Session.class); mockSession.setUser(user); replay(mockSession); Authenticator authenticator = new Authenticator(stubRepository); authenticator.authenticate("bob", mockSession); verify(mockSession); } }
  23. import org.junit.Test; import static org.easymock.EasyMock.*; public class AuthenticatorTest { @Test

    public void testAuthenticate() { User user = new User(); Repository stubRepository = createMock(Repository.class); expect(stubRepository.findUser("bob")).andStubReturn(user); replay(stubRepository); Session mockSession = createMock(Session.class); mockSession.setUser(user); replay(mockSession); Authenticator authenticator = new Authenticator(stubRepository); authenticator.authenticate("bob", mockSession); verify(mockSession); } }
  24. JUnit version 4.11 .E Time: 0.045 There was 1 failure:

    1) testAuthenticate(AuthenticatorTest) java.lang.AssertionError: Expectation failure on verify: Session.setUser(User@27f8302d): expected: 1, actual: 0 at org.easymock.internal.MocksControl.verify (MocksControl.java:226) ... FAILURES!!! Tests run: 1, Failures: 1
  25. JUnit version 4.11 .E Time: 0.045 There was 1 failure:

    1) testAuthenticate(AuthenticatorTest) java.lang.AssertionError: Expectation failure on verify: Session.setUser(User@27f8302d): expected: 1, actual: 0 at org.easymock.internal.MocksControl.verify (MocksControl.java:226) ... FAILURES!!! Tests run: 1, Failures: 1
  26. public class Authenticator { private Repository repository; public Authenticator(final Repository

    repository) { this.repository = repository; } public void authenticate(String username, Session session) { User user = repository.findUser(username); session.setUser(user); } }
  27. package com.example.calculator; import static org.junit.Assert.*; import org.junit.*; import com.example.Calculator; public

    class CalculatorTests { private Calculator calc; @Before public void SetUp() { calc = new Calculator(); } @Test public void testAddition() { calc.push("4"); calc.push("+"); calc.push("5"); assertEquals("9", calc.value()); } }
  28. Feature: Basic Arithmetic Background: A Calculator Given a calculator I

    just turned on Scenario: Addition When I add 4 and 5 Then the result is 9 Scenario: Subtraction When I subtract 4 from 10 Then the result is 6
  29. public class CalculatorStepdefs { private Calculator calc; @Given("^a calculator I

    just turned on$") public void a_calculator_I_just_turned_on() { calc = new Calculator(); } @When("^I add (\\d+) and (\\d+)$") public void adding(int arg1, int arg2) { calc.push(arg1); calc.push("+"); calc.push(arg2); } @Then("^the result is (\\d+)$") public void the_result_is(double expected) { assertEquals(expected, calc.value()); } }
  30. public class CalculatorStepdefs { private Calculator calc; @Given("^a calculator I

    just turned on$") public void a_calculator_I_just_turned_on() { calc = new Calculator(); } @When("^I add (\\d+) and (\\d+)$") public void adding(int arg1, int arg2) { calc.push(arg1); calc.push("+"); calc.push(arg2); } @Then("^the result is (\\d+)$") public void the_result_is(double expected) { assertEquals(expected, calc.value()); } }
  31. public class CalculatorStepdefs { private Calculator calc; @Given("^a calculator I

    just turned on$") public void a_calculator_I_just_turned_on() { calc = new Calculator(); } @When("^I add (\\d+) and (\\d+)$") public void adding(int arg1, int arg2) { calc.push(arg1); calc.push("+"); calc.push(arg2); } @Then("^the result is (\\d+)$") public void the_result_is(double expected) { assertEquals(expected, calc.value()); } }
  32. public class CalculatorStepdefs { private Calculator calc; @Given("^a calculator I

    just turned on$") public void a_calculator_I_just_turned_on() { calc = new Calculator(); } @When("^I add (\\d+) and (\\d+)$") public void adding(int arg1, int arg2) { calc.push(arg1); calc.push("+"); calc.push(arg2); } @Then("^the result is (\\d+)$") public void the_result_is(double expected) { assertEquals(expected, calc.value()); } }
  33. public class CalculatorStepdefs { private Calculator calc; @Given("^a calculator I

    just turned on$") public void a_calculator_I_just_turned_on() { calc = new Calculator(); } @When("^I add (\\d+) and (\\d+)$") public void adding(int arg1, int arg2) { calc.push(arg1); calc.push("+"); calc.push(arg2); } @Then("^the result is (\\d+)$") public void the_result_is(double expected) { assertEquals(expected, calc.value()); } }
  34. public class CalculatorStepdefs { private Calculator calc; @Given("^a calculator I

    just turned on$") public void a_calculator_I_just_turned_on() { calc = new Calculator(); } @When("^I add (\\d+) and (\\d+)$") public void adding(int arg1, int arg2) { calc.push(arg1); calc.push("+"); calc.push(arg2); } @Then("^the result is (\\d+)$") public void the_result_is(double expected) { assertEquals(expected, calc.value()); } }
  35. Feature: Finding train times Scenario: Search for a single journey

    Given it is 17.30 on 25/10/2014 When I want to travel from Ipswich to Liverpool Street And I want to travel on 27/10/2014 And I search for trains Then the first train should leave at 17:43 public class TrainTimesStepdefs { @When("^I want to travel from (.+) to (.+)$”) public void chooseStations(String from, String to) { WebDriver driver = new FirefoxDriver(); driver.get(“http://www.nationalrail.co.uk/"); element = driver.findElement(By.name("txtFrom")); element.sendKeys(from); element = driver.findElement(By.name("txtTo")); element.sendKeys(to); } }
  36. Feature: Finding train times Scenario: Search for a single journey

    Given it is 17.30 on 25/10/2014 When I want to travel from Ipswich to Liverpool Street And I want to travel on 27/10/2014 And I search for trains Then the first train should leave at 17:43 public class TrainTimesStepdefs { @When("^I want to travel from (.+) to (.+)$") public void chooseStations(String from, String to) { WebDriver driver = new FirefoxDriver(); driver.get("http://www.nationalrail.co.uk/"); element = driver.findElement(By.name("txtFrom")); element.sendKeys(from); element = driver.findElement(By.name("txtTo")); element.sendKeys(to); } }
  37. Feature: Finding train times Scenario: Search for a single journey

    Given it is 17.30 on 25/10/2014 When I want to travel from Ipswich to Liverpool Street And I want to travel on 27/10/2014 And I search for trains Then the first train should leave at 17:43 public class TrainTimesStepdefs { @When("^I want to travel from (.+) to (.+)$") public void chooseStations(String from, String to) { WebDriver driver = new FirefoxDriver(); driver.get("http://www.nationalrail.co.uk/"); element = driver.findElement(By.name("txtFrom")); element.sendKeys(from); element = driver.findElement(By.name("txtTo")); element.sendKeys(to); } }
  38. Feature: Finding train times Scenario: Search for a single journey

    Given it is 17.30 on 25/10/2014 When I want to travel from Ipswich to Liverpool Street And I want to travel on 27/10/2014 And I search for trains Then the first train should leave at 17:43 public class TrainTimesStepdefs { @When("^I want to travel from (.+) to (.+)$") public void chooseStations(String from, String to) { WebDriver driver = new FirefoxDriver(); driver.get("http://www.nationalrail.co.uk/"); element = driver.findElement(By.name("txtFrom")); element.sendKeys(from); element = driver.findElement(By.name("txtTo")); element.sendKeys(to); } }