This document discusses testing and testable code. It will cover test driven development, testing, and creating testable code. The speaker will discuss two common pitfalls when doing TDD - acting as a "TDD prophet" or "TDD architect". True TDD practice involves picking a requirement, writing a test for it, making the test fail, writing code to make it pass, and refactoring. Bugs driven tests and creating testable code from the beginning are recommended for learning TDD. Testable code should be declarative, easy to read and test, and promote good design.
75. Testing and testable code @Test public void testUserCreation() throws Exception { User user = new User(); }
76. Testing and testable code @Test public void testUserHasLoginAndPassword() throws Exception { User user = new User(); user.setLogin("login"); user.setPassword("password"); assertEquals("login", user.getLogin()); assertEquals("password", user.getPassword()); }
77. Testing and testable code @Test public void testEqualsMethodValidForSameLogin() throws Exception { User user1 = new User(); user1.setLogin("login"); User user2 = new User(); user2.setLogin("login"); assertEquals(user1, user2); }
78. Testing and testable code @Test public void testEqualsMethodReturnsFalseForDifferentLogin() throws Exception { User user1 = new User(); user1.setLogin("login"); User user2 = new User(); user2.setLogin("login2"); assertFalse(user1.equals(user2)); }
79. Testing and testable code @Test public void testEqualsHashCodeConstract() throws Exception { User user1 = new User(); user1.setLogin("login"); User user2 = new User(); user2.setLogin("login"); assertTrue(user1.equals(user2)); assertEquals(user1.hashCode(),user2.hashCode()); }
80. Testing and testable code public class User { private String login, password; public User() { } public String getLogin() { return login; } public void setLogin(String login) { this.login = login; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; User user = (User) o; if (!login.equals(user.login)) return false; return true; } public int hashCode() { return login.hashCode(); } } Design you get:
91. Testing and testable code … the test should really looked like this: @Test public void shouldLoginForCorrectLoginAndPassword() throws Exception{ // given String login = "login"; String password = "password"; dao.persist(new User(login,password)); // when User user = service.logIn(login, password); // then assertEquals(login, user.getLogin()); assertEquals(password, user.getPassword()); }
92. Testing and testable code public class User { private String login, password; public User(String login, String password) { this.login = login; this.password = password; } public String getLogin() { return login; } public String getPassword() { return password; } } Design you get:
93. Testing and testable code public class User { private String login, password; public User() { } public String getLogin() { return login; } public void setLogin(String login) { this.login = login; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; User user = (User) o; if (!login.equals(user.login)) return false; return true; } public int hashCode() { return login.hashCode(); } } public class User { private String login, password; public User(String login, String password) { this.login = login; this.password = password; } public String getLogin() { return login; } public String getPassword() { return password; } }
94.
95. Smallest change in your code make a lot of tests fail, even if that change isn't caused be change of requirements
224. A and B does not know anything about each other
225.
226.
227. Test are not isolated, even if they look like they are ” You may not have thought of it this way before, but whenever you use static state, you’re creating secret communication channels and not making them clear in the API.”