├── README.md ├── asserting_private_methods └── src │ ├── main │ └── java │ │ └── com │ │ └── practicalunittesting │ │ ├── AndroidTransaction.java │ │ ├── AndroidTransactionState.java │ │ ├── AndroidTransactionStep.java │ │ ├── Client.java │ │ ├── ClientMessage.java │ │ ├── ExtendedState.java │ │ ├── Processor.java │ │ ├── RequestType.java │ │ ├── ResultCode.java │ │ └── TxDTO.java │ └── test │ └── java │ └── com │ └── practicalunittesting │ ├── CustomAssertionsTest.java │ └── OriginalTest.java ├── autogeneration └── src │ └── test │ └── java │ └── com │ └── practicalunittesting │ ├── Adapter.java │ └── AutogenerationTest.java ├── build.gradle ├── builders └── src │ └── test │ └── java │ └── com │ └── practicalunittesting │ └── BigDecimalBuilderTest.java ├── ceremony └── src │ ├── main │ └── java │ │ └── com │ │ └── practicalunittesting │ │ ├── Administrator.java │ │ ├── EmailUtils.java │ │ └── User.java │ └── test │ └── java │ └── com │ └── practicalunittesting │ ├── AdministratorTest.java │ └── EmailSenderTest.java ├── change_test_after_logic_is_changed └── src │ ├── main │ └── java │ │ └── com │ │ └── practicalunittesting │ │ ├── ExternalUser.java │ │ ├── InternalUser.java │ │ ├── Transaction.java │ │ └── User.java │ └── test │ └── java │ └── com │ └── practicalunittesting │ └── TransactionTest.java ├── copy_and_paste └── src │ ├── main │ └── java │ │ └── com │ │ └── practicalunittesting │ │ ├── Artifact.java │ │ └── Type.java │ └── test │ └── java │ └── com │ └── practicalunittesting │ ├── SnapshotArtifactsImprovedTests.java │ └── SnapshotArtifactsTest.java ├── creation_of_objects └── src │ ├── main │ └── java │ │ └── com │ │ └── practicalunittesting │ │ ├── Address.java │ │ ├── Company.java │ │ ├── MockServer.java │ │ ├── ProductCategory.java │ │ ├── ResponseType.java │ │ ├── User.java │ │ ├── UserBuilder.java │ │ └── UserState.java │ └── test │ └── java │ └── com │ └── practicalunittesting │ ├── MockServerBuilder.java │ ├── SimpleTypeTest.java │ ├── UserBuilderTest.java │ └── UserTest.java ├── database_assumption └── src │ ├── main │ └── java │ │ └── com │ │ └── practicalunittesting │ │ ├── User.java │ │ ├── UserDAO.java │ │ └── UserService.java │ └── test │ └── java │ └── com │ └── practicalunittesting │ └── UserServiceTest.java ├── email └── src │ ├── main │ └── java │ │ └── com │ │ └── practicalunittesting │ │ ├── Email.java │ │ └── EmailDAO.java │ └── test │ └── java │ └── com │ └── practicalunittesting │ └── EmailDAOTest.java ├── expected_exceptions └── src │ ├── main │ └── java │ │ └── com │ │ └── practicalunittesting │ │ ├── DnsService.java │ │ ├── Domain.java │ │ ├── DomainRegistrator.java │ │ └── DomainService.java │ └── test │ └── java │ └── com │ └── practicalunittesting │ └── ExpectedExceptionsTest.java ├── fizzbuzz └── src │ ├── main │ └── java │ │ └── com │ │ └── practicalunittesting │ │ └── FizzBuzz.java │ └── test │ └── java │ └── com │ └── practicalunittesting │ └── testng │ ├── FizzBuzzJUnitTest.java │ └── FizzBuzzTest.java ├── fizzbuzz_original └── src │ ├── main │ └── java │ │ └── com │ │ └── practicalunittesting │ │ └── FizzBuzz.java │ └── test │ └── java │ └── com │ └── practicalunittesting │ └── FizzBuzzTest.java ├── form └── src │ ├── main │ └── java │ │ └── com │ │ └── practicalunittesting │ │ └── Form.java │ └── test │ └── java │ └── com │ └── practicalunittesting │ └── FormTest.java ├── global_state └── src │ ├── main │ └── java │ │ └── com │ │ └── practicalunittesting │ │ ├── BaseServletContextListener.java │ │ ├── LoggingInitialisationException.java │ │ └── LoggingPropertyConfigurator.java │ └── test │ └── java │ └── com │ └── practicalunittesting │ ├── FlickeringTest.java │ └── NoLongerFlickeringTest.java ├── localized_exceptions └── src │ ├── main │ └── java │ │ └── com │ │ └── practicalunittesting │ │ ├── MaliciousMyList.java │ │ └── MyList.java │ └── test │ └── java │ └── com │ └── practicalunittesting │ ├── MaliciousMyListTest.java │ └── updated │ ├── MyListCatchExceptionTest.java │ ├── MyListTryCatchFestAssertTest.java │ └── MyListTryCatchTest.java ├── mock_counter └── src │ ├── main │ └── java │ │ └── com │ │ └── practicalunittesting │ │ ├── City.java │ │ └── District.java │ └── test │ └── java │ └── com │ └── practicalunittesting │ └── CityTest.java ├── mocking_container └── src │ ├── main │ └── java │ │ └── com │ │ └── practicalunittesting │ │ ├── Context.java │ │ └── UserDataInterceptor.java │ └── test │ └── java │ └── com │ └── practicalunittesting │ └── MockingContainerTest.java ├── mocks_are_good └── src │ ├── main │ └── java │ │ └── com │ │ └── practicalunittesting │ │ ├── Report.java │ │ ├── TrafficService.java │ │ ├── TrafficTrend.java │ │ └── TrafficTrendProvider.java │ └── test │ └── java │ └── com │ └── practicalunittesting │ └── TrafficTest.java ├── no_assertions └── src │ └── test │ └── java │ └── com │ └── practicalunittesting │ ├── Format.java │ ├── IResult.java │ └── NoAssertionsTest.java ├── object123 └── src │ ├── main │ └── java │ │ └── com │ │ └── practicalunittesting │ │ ├── DaoTestHelper.java │ │ ├── Product.java │ │ ├── ProductUserState.java │ │ └── User.java │ └── test │ └── java │ └── com │ └── practicalunittesting │ └── ImportantTest.java ├── pager └── src │ ├── main │ └── java │ │ └── com │ │ └── practicalunittesting │ │ └── Pager.java │ └── test │ └── java │ └── com │ └── practicalunittesting │ └── PagerTest.java ├── printwriter └── src │ ├── main │ └── java │ │ └── com │ │ └── practicalunittesting │ │ ├── Filter.java │ │ ├── ReportController.java │ │ ├── ReportData.java │ │ └── ReportService.java │ └── test │ └── java │ └── com │ └── practicalunittesting │ ├── ControllerTest.java │ └── ControllerWithStringWriterTest.java ├── self_test └── src │ ├── main │ └── java │ │ └── com │ │ └── practicalunittesting │ │ └── PaymentMethod.java │ └── test │ └── java │ └── com │ └── practicalunittesting │ └── PaymentMethodTest.java ├── settings.gradle ├── smart_values └── src │ ├── main │ └── java │ │ └── com │ │ └── practicalunittesting │ │ ├── PriceCalculator.java │ │ ├── PriceCalculatorFactory.java │ │ └── SettingsService.java │ └── test │ └── java │ └── com │ └── practicalunittesting │ ├── ImprovedPriceCalculatorFactoryTest.java │ └── PriceCalculatorFactoryTest.java ├── test_behaviour └── src │ ├── main │ └── java │ │ └── com │ │ └── practicalunittesting │ │ ├── MailSender.java │ │ ├── User.java │ │ ├── UserData.java │ │ ├── UserRegisterController.java │ │ └── UserService.java │ └── test │ └── java │ └── com │ └── practicalunittesting │ └── UserRegisterControllerTest.java ├── time_means_trouble └── src │ ├── main │ └── java │ │ └── com │ │ └── practicalunittesting │ │ ├── TimeProvider.java │ │ ├── User.java │ │ ├── Util.java │ │ └── Util2.java │ └── test │ └── java │ └── com │ └── practicalunittesting │ ├── Util2Test.java │ └── UtilTest.java ├── true_false └── src │ ├── main │ └── java │ │ └── com │ │ └── practicalunittesting │ │ ├── MockServer.java │ │ └── ResponseType.java │ └── test │ └── java │ └── com │ └── practicalunittesting │ ├── BuilderTest.java │ ├── ConstantsTest.java │ ├── OriginalTest.java │ └── PrivateMethodTest.java ├── valid_and_not_valid └── src │ ├── main │ └── java │ │ └── com │ │ └── practicalunittesting │ │ └── FieldVerifier.java │ └── test │ └── java │ └── com │ └── practicalunittesting │ ├── ImprovedQueryTest.java │ └── QueryTest.java ├── verify_never └── src │ ├── main │ └── java │ │ └── com │ │ └── practicalunittesting │ │ ├── PacketApi.java │ │ ├── PacketDataProcessor.java │ │ └── PacketServlet.java │ └── test │ └── java │ └── com │ └── practicalunittesting │ └── PacketServletTest.java ├── waste_of_time └── src │ ├── main │ └── java │ │ └── com │ │ └── practicalunittesting │ │ ├── Settings.java │ │ └── SettingsFacade.java │ └── test │ └── java │ └── com │ └── practicalunittesting │ └── SettingsFacadeTest.java ├── what_is_asserted └── src │ ├── main │ └── java │ │ └── com │ │ └── practicalunittesting │ │ ├── CompilerSupport.java │ │ └── CompilerSupportFactory.java │ └── test │ └── java │ └── com │ └── practicalunittesting │ └── CompilerTest.java └── zeros_are_evil └── src ├── main └── java │ └── com │ └── practicalunittesting │ └── zero │ ├── Client.java │ ├── PaymentAdapter.java │ └── PaymentService.java └── test └── java └── com └── practicalunittesting └── zero ├── PaymentServiceNonZeroTest.java └── PaymentServiceTest.java /README.md: -------------------------------------------------------------------------------- 1 | bad-tests-good-tests-code 2 | ========================= 3 | 4 | code snippets from "Bad Tests, Good Tests" book (see http://practicalunittesting.com) 5 | -------------------------------------------------------------------------------- /asserting_private_methods/src/main/java/com/practicalunittesting/AndroidTransaction.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public class AndroidTransaction { 4 | public int getTransactionSteps() { 5 | return 0; 6 | } 7 | 8 | public AndroidTransactionState getState() { 9 | return null; 10 | } 11 | 12 | public ExtendedState getExtendedState() { 13 | return null; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /asserting_private_methods/src/main/java/com/practicalunittesting/AndroidTransactionState.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public enum AndroidTransactionState { 4 | CHARGE_PENDING, CHARGED 5 | } 6 | -------------------------------------------------------------------------------- /asserting_private_methods/src/main/java/com/practicalunittesting/AndroidTransactionStep.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public class AndroidTransactionStep { 4 | public AndroidTransactionState getTransactionState() { 5 | return null; 6 | } 7 | 8 | public String getMessage() { 9 | return null; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /asserting_private_methods/src/main/java/com/practicalunittesting/Client.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public class Client { 4 | } 5 | -------------------------------------------------------------------------------- /asserting_private_methods/src/main/java/com/practicalunittesting/ClientMessage.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public class ClientMessage { 4 | public static final String SUCCESS = "success"; 5 | } 6 | -------------------------------------------------------------------------------- /asserting_private_methods/src/main/java/com/practicalunittesting/ExtendedState.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public enum ExtendedState { 4 | AS_ANDROID_TX_STATE 5 | } 6 | -------------------------------------------------------------------------------- /asserting_private_methods/src/main/java/com/practicalunittesting/Processor.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public class Processor { 4 | public TxDTO processRequest(TxDTO request) { 5 | return null; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /asserting_private_methods/src/main/java/com/practicalunittesting/RequestType.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public enum RequestType { 4 | CHARGE 5 | } 6 | -------------------------------------------------------------------------------- /asserting_private_methods/src/main/java/com/practicalunittesting/ResultCode.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public enum ResultCode { 4 | SUCCESS 5 | } 6 | -------------------------------------------------------------------------------- /asserting_private_methods/src/main/java/com/practicalunittesting/TxDTO.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public class TxDTO { 4 | public ResultCode getResultCode() { 5 | return null; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /asserting_private_methods/src/test/java/com/practicalunittesting/CustomAssertionsTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.testng.annotations.Test; 4 | 5 | public class CustomAssertionsTest { 6 | 7 | Processor processor = new Processor(); 8 | 9 | @Test 10 | public void testChargeInRetryingState() throws Exception { 11 | // given 12 | TxDTO request = createTxDTO(RequestType.CHARGE); 13 | AndroidTransaction androidTransaction = createAndroidTx(); 14 | // when 15 | final TxDTO txDTO = processor.processRequest(request); 16 | // then 17 | // assertThat(androidTransaction).hasState(AndroidTransactionState.CHARGED) 18 | // .hasMessage(ClientMessage.SUCCESS) 19 | // .hasPreviousState(AndroidTransactionState.CHARGE_PENDING) 20 | // .hasExtendedState(null); 21 | // assertEquals(txDTO.getResultCode(), 22 | // ResultCode.SUCCESS); 23 | } 24 | 25 | private AndroidTransaction createAndroidTx() { 26 | return null; 27 | } 28 | 29 | private TxDTO createTxDTO(RequestType requestType) { 30 | return null; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /asserting_private_methods/src/test/java/com/practicalunittesting/OriginalTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.testng.annotations.Test; 4 | 5 | import java.sql.ClientInfoStatus; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | import static org.mockito.Mockito.verifyZeroInteractions; 10 | import static org.testng.Assert.assertEquals; 11 | import static org.testng.Assert.assertTrue; 12 | 13 | public class OriginalTest { 14 | 15 | Processor processor = new Processor(); 16 | Client client = new Client(); 17 | @Test 18 | public void testChargeInRetryingState() throws Exception { 19 | // given 20 | TxDTO request = createTxDTO(RequestType.CHARGE); 21 | AndroidTransaction androidTransaction = createAndroidTx(); 22 | 23 | // when 24 | final TxDTO txDTO = processor.processRequest(request); 25 | 26 | // then 27 | assertState(txDTO, androidTransaction, 28 | AndroidTransactionState.CHARGED, AndroidTransactionState.CHARGE_PENDING, ExtendedState.AS_ANDROID_TX_STATE, 29 | ClientMessage.SUCCESS, ResultCode.SUCCESS); 30 | } 31 | 32 | private AndroidTransaction createAndroidTx() { 33 | return null; 34 | } 35 | 36 | private TxDTO createTxDTO(RequestType requestType) { 37 | return null; 38 | } 39 | 40 | private void assertState(TxDTO txDTO, AndroidTransaction androidTransaction, 41 | AndroidTransactionState expectedAndroidState, 42 | AndroidTransactionState expectedPreviousAndroidState, 43 | ExtendedState expectedState, 44 | String expectedClientStatus, 45 | ResultCode expectedRequestResultCode) { 46 | final List steps 47 | = new ArrayList(androidTransaction.getTransactionSteps()); 48 | final boolean checkPreviousStep = expectedAndroidState != null; 49 | assertTrue(steps.size() >= (checkPreviousStep ? 3 : 2)); 50 | 51 | if (checkPreviousStep) { 52 | AndroidTransactionStep lastStep = steps.get(steps.size() - 2); 53 | assertEquals(lastStep.getTransactionState(), 54 | expectedPreviousAndroidState); 55 | } 56 | 57 | final AndroidTransactionStep lastStep = steps.get(steps.size() - 1); 58 | assertEquals(lastStep.getTransactionState(), expectedAndroidState); 59 | assertEquals(lastStep.getMessage(), expectedClientStatus); 60 | 61 | assertEquals(txDTO.getResultCode(), expectedRequestResultCode); 62 | assertEquals(androidTransaction.getState(), expectedAndroidState); 63 | assertEquals(androidTransaction.getExtendedState(), expectedState); 64 | 65 | if (expectedClientStatus == null) { 66 | verifyZeroInteractions(client); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /autogeneration/src/test/java/com/practicalunittesting/Adapter.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import java.util.Calendar; 4 | 5 | public interface Adapter { 6 | void setTimestamp(Calendar test); 7 | 8 | Calendar getTimestamp(); 9 | 10 | void setParam(String test); 11 | 12 | String getParam(); 13 | } 14 | -------------------------------------------------------------------------------- /autogeneration/src/test/java/com/practicalunittesting/AutogenerationTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.testng.annotations.Test; 4 | 5 | import java.util.GregorianCalendar; 6 | 7 | import static org.testng.Assert.assertEquals; 8 | 9 | @Test 10 | public class AutogenerationTest { 11 | 12 | Adapter adapter; 13 | public void testSetGetTimestamp() throws Exception { 14 | // JUnitDoclet begin method setTimestamp getTimestamp 15 | java.util.Calendar[] tests = {new GregorianCalendar(), null}; 16 | for (int i = 0; i < tests.length; i++) { 17 | adapter.setTimestamp(tests[i]); 18 | assertEquals(tests[i], adapter.getTimestamp()); 19 | } 20 | } 21 | // JUnitDoclet end method setTimestamp getTimestamp 22 | public void testSetGetParam() throws Exception { 23 | // JUnitDoclet begin method setParam getParam 24 | String[] tests = {"a", "aaa", "---", "23121313", "", null}; 25 | for (int i = 0; i < tests.length; i++) { 26 | adapter.setParam(tests[i]); 27 | assertEquals(tests[i], adapter.getParam()); 28 | } 29 | // JUnitDoclet end method setParam getParam 30 | 31 | } 32 | } -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | defaultTasks 'build' 2 | 3 | allprojects { 4 | apply plugin: 'idea'; 5 | sourceCompatibility = 1.6 6 | } 7 | 8 | subprojects { 9 | apply plugin: 'java' 10 | 11 | repositories { 12 | mavenCentral() 13 | } 14 | 15 | dependencies { 16 | testCompile 'junit:junit:4.10' 17 | testCompile 'pl.pragmatists:JUnitParams:1.0.2' 18 | testCompile 'org.testng:testng:6.8' 19 | testCompile 'org.mockito:mockito-all:1.9.0' 20 | testCompile 'org.hamcrest:hamcrest-all:1.3' 21 | testCompile 'org.assertj:assertj-core:1.5.0' 22 | testCompile 'com.googlecode.catch-exception:catch-exception:1.0.4' 23 | } 24 | 25 | idea { 26 | module.downloadSources = true; 27 | } 28 | } 29 | 30 | project(':printwriter') { 31 | dependencies { 32 | compile 'org.glassfish:javax.servlet:3.0' 33 | compile 'org.springframework:spring-web:3.0.0.RELEASE' 34 | } 35 | } 36 | 37 | project('self_test') { 38 | dependencies { 39 | compile 'com.google.guava:guava:15.0' 40 | } 41 | } 42 | 43 | project(':verify_never') { 44 | dependencies { 45 | compile 'org.glassfish:javax.servlet:3.0' 46 | } 47 | } 48 | 49 | project(':mocking_container') { 50 | dependencies { 51 | compile 'org.springframework:spring-webmvc:4.0.0.RELEASE' 52 | } 53 | } 54 | 55 | project(':test_behaviour') { 56 | dependencies { 57 | compile 'org.glassfish:javax.servlet:3.0' 58 | compile 'org.springframework:spring-webmvc:4.0.0.RELEASE' 59 | } 60 | } 61 | 62 | project(':creation_of_objects') { 63 | dependencies { 64 | compile 'joda-time:joda-time:2.3' 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /builders/src/test/java/com/practicalunittesting/BigDecimalBuilderTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.junit.Test; 4 | 5 | import java.math.BigDecimal; 6 | import java.util.Arrays; 7 | import java.util.List; 8 | 9 | public class BigDecimalBuilderTest { 10 | 11 | @Test 12 | public void someTest() { 13 | List categories = Arrays.asList( 14 | product("car", new BigDecimal("100"), new BigDecimal("10000")), 15 | product("bike", new BigDecimal("20"), new BigDecimal("5000")), 16 | product("plane", new BigDecimal("1000"), new BigDecimal("500000")) 17 | ); 18 | 19 | List categories2 = Arrays.asList( 20 | product("car", 100, 10000), 21 | product("bike", 20, 5000), 22 | product("plane", 1000, 500000) 23 | ); 24 | } 25 | 26 | private ProductCategory product(String productCategory, BigDecimal priceFrom, BigDecimal priceTo) { 27 | return null; // does not matter 28 | } 29 | 30 | private ProductCategory product(String productCategory, int priceFrom, int priceTo) { 31 | return product(productCategory, BigDecimal.valueOf(priceFrom), BigDecimal.valueOf(priceTo)); 32 | } 33 | 34 | private class ProductCategory { 35 | // who cares? 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ceremony/src/main/java/com/practicalunittesting/Administrator.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public class Administrator implements User { 4 | @Override 5 | public boolean isAdministrator() { 6 | return true; 7 | } 8 | 9 | @Override 10 | public boolean isGuest() { 11 | return false; 12 | } 13 | 14 | @Override 15 | public boolean isModerator() { 16 | return false; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ceremony/src/main/java/com/practicalunittesting/EmailUtils.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public class EmailUtils { 4 | public static String buildEmailSender(String senderName, String senderEmail) { 5 | return null; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /ceremony/src/main/java/com/practicalunittesting/User.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public interface User { 4 | boolean isAdministrator(); 5 | 6 | boolean isGuest(); 7 | 8 | boolean isModerator(); 9 | } 10 | -------------------------------------------------------------------------------- /ceremony/src/test/java/com/practicalunittesting/AdministratorTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.assertj.core.api.Assertions.assertThat; 6 | 7 | public class AdministratorTest { 8 | 9 | @Test 10 | public void shouldBeAdministrator() { 11 | //given 12 | User user = new Administrator(); 13 | 14 | //when 15 | boolean administrator = user.isAdministrator(); 16 | boolean guest = user.isGuest(); 17 | boolean moderator = user.isModerator(); 18 | 19 | //then 20 | assertThat(administrator).isTrue(); 21 | assertThat(guest).isFalse(); 22 | assertThat(moderator).isFalse(); 23 | } 24 | 25 | @Test 26 | public void shouldBeAdministrator_ShorterVersion() { 27 | User user = new Administrator(); 28 | 29 | assertThat(user.isAdministrator()).isTrue(); 30 | assertThat(user.isGuest()).isFalse(); 31 | assertThat(user.isModerator()).isFalse(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ceremony/src/test/java/com/practicalunittesting/EmailSenderTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.assertj.core.api.Assertions.assertThat; 6 | 7 | public class EmailSenderTest { 8 | 9 | @Test 10 | public void shouldBuildEmailSender() { 11 | // given 12 | String senderName = "Chuck Norris"; 13 | String senderEmail = "chuck@norris.com"; 14 | 15 | // when 16 | String emailSender = EmailUtils.buildEmailSender(senderName, senderEmail); 17 | 18 | // then 19 | assertThat(emailSender).isEqualTo("Chuck Norris "); 20 | } 21 | 22 | @Test 23 | public void shouldBuildEmailSender_TwoLines() { 24 | String emailSender = EmailUtils 25 | .buildEmailSender("Chuck Norris", "chuck@norris.com"); 26 | assertThat(emailSender).isEqualTo("Chuck Norris "); 27 | } 28 | 29 | @Test 30 | public void shouldBuildEmailSender_OneLiner() { 31 | assertThat(EmailUtils.buildEmailSender("Chuck Norris","chuck@norris.com")) 32 | .isEqualTo("Chuck Norris "); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /change_test_after_logic_is_changed/src/main/java/com/practicalunittesting/ExternalUser.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public class ExternalUser extends User { 4 | 5 | @Override 6 | public boolean isExternal() { 7 | return true; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /change_test_after_logic_is_changed/src/main/java/com/practicalunittesting/InternalUser.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public class InternalUser extends User { 4 | 5 | @Override 6 | public boolean isExternal() { 7 | return false; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /change_test_after_logic_is_changed/src/main/java/com/practicalunittesting/Transaction.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import java.math.BigDecimal; 4 | 5 | public class Transaction { 6 | 7 | private final BigDecimal amount; 8 | private final User user; 9 | 10 | public Transaction(BigDecimal amount, User user) { 11 | this.amount = amount; 12 | this.user = user; 13 | } 14 | 15 | public boolean validate() { 16 | if (!user.isExternal()) { 17 | return false; 18 | } 19 | return amount.compareTo(BigDecimal.ZERO) > 0; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /change_test_after_logic_is_changed/src/main/java/com/practicalunittesting/User.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | 4 | public abstract class User { 5 | 6 | public abstract boolean isExternal(); 7 | 8 | } 9 | -------------------------------------------------------------------------------- /change_test_after_logic_is_changed/src/test/java/com/practicalunittesting/TransactionTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.junit.Test; 4 | 5 | import java.math.BigDecimal; 6 | 7 | import static org.assertj.core.api.Assertions.assertThat; 8 | 9 | public class TransactionTest { 10 | 11 | @Test 12 | public void shouldRecognizeTransactionsWithZeroValueAsInvalid() { 13 | //given 14 | Transaction transaction = new Transaction(BigDecimal.ZERO, new InternalUser()); 15 | 16 | //when 17 | boolean actual = transaction.validate(); 18 | 19 | //then 20 | assertThat(actual).isFalse(); 21 | } 22 | 23 | @Test 24 | public void shouldRecognizeTransactionWithNegativeValueAsInvalid() { 25 | //given 26 | Transaction transaction = new Transaction(BigDecimal.ONE.negate(), new InternalUser()); 27 | 28 | //when 29 | boolean actual = transaction.validate(); 30 | 31 | //then 32 | assertThat(actual).isFalse(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /copy_and_paste/src/main/java/com/practicalunittesting/Artifact.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public class Artifact { 4 | private final String groupId; 5 | private final String artifactId; 6 | private final String version; 7 | private final Type type; 8 | 9 | public Artifact(String groupId, String artifactId, String version, Type type) { 10 | 11 | this.groupId = groupId; 12 | this.artifactId = artifactId; 13 | this.version = version; 14 | this.type = type; 15 | } 16 | 17 | public boolean isSnapshot() { 18 | return version.endsWith("SNAPSHOT"); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /copy_and_paste/src/main/java/com/practicalunittesting/Type.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public enum Type { 4 | JAR 5 | } 6 | -------------------------------------------------------------------------------- /copy_and_paste/src/test/java/com/practicalunittesting/SnapshotArtifactsImprovedTests.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.testng.annotations.DataProvider; 4 | import org.testng.annotations.Test; 5 | 6 | import static org.assertj.core.api.Assertions.assertThat; 7 | 8 | public class SnapshotArtifactsImprovedTests { 9 | 10 | private static final String VALID_GROUP = "group"; 11 | private static final String VALID_ARTIFACT_ID = "artifact_id"; 12 | private static final Type VALID_TYPE = Type.JAR; 13 | 14 | @DataProvider 15 | public Object[][] snapshotVersions() { 16 | return new Object[][]{ 17 | {"2.2-SNAPSHOT"}, 18 | {"2.2.4.6-SNAPSHOT"}, 19 | {"2-SNAPSHOT"} 20 | }; 21 | } 22 | 23 | @Test(dataProvider = "snapshotVersions") 24 | public void shouldRecognizeSnapshots(String version) { 25 | Artifact artifact 26 | = new Artifact(VALID_GROUP, VALID_ARTIFACT_ID, 27 | version, VALID_TYPE); 28 | assertThat(artifact.isSnapshot()).isTrue(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /copy_and_paste/src/test/java/com/practicalunittesting/SnapshotArtifactsTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.testng.annotations.DataProvider; 4 | import org.testng.annotations.Test; 5 | 6 | import static org.assertj.core.api.Assertions.assertThat; 7 | 8 | 9 | public class SnapshotArtifactsTest { 10 | 11 | @DataProvider 12 | public Object[][] snapshotArtifacts() { 13 | return new Object[][]{ 14 | {"a", "b", "2.2-SNAPSHOT", Type.JAR }, 15 | {"c", "d", "2.2.4.6-SNAPSHOT", Type.JAR}, 16 | {"e", "f", "2-SNAPSHOT", Type.JAR} 17 | }; 18 | } 19 | 20 | @Test(dataProvider = "snapshotArtifacts") 21 | public void shouldRecognizeSnapshots( 22 | String groupId, String artifactId, 23 | String version, Type type) { 24 | Artifact artifact 25 | = new Artifact(groupId, artifactId, version, type); 26 | assertThat(artifact.isSnapshot()).isTrue(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /creation_of_objects/src/main/java/com/practicalunittesting/Address.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public class Address { 4 | } 5 | -------------------------------------------------------------------------------- /creation_of_objects/src/main/java/com/practicalunittesting/Company.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public interface Company { 4 | } 5 | -------------------------------------------------------------------------------- /creation_of_objects/src/main/java/com/practicalunittesting/MockServer.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import java.util.Map; 4 | 5 | public class MockServer { 6 | public MockServer(Map stringMap, ResponseType responseType, String serverUrl, boolean ssl) { 7 | 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /creation_of_objects/src/main/java/com/practicalunittesting/ProductCategory.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public interface ProductCategory { 4 | } 5 | -------------------------------------------------------------------------------- /creation_of_objects/src/main/java/com/practicalunittesting/ResponseType.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public interface ResponseType { 4 | } 5 | -------------------------------------------------------------------------------- /creation_of_objects/src/main/java/com/practicalunittesting/User.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import java.util.Date; 4 | 5 | public class User { 6 | private Company company; 7 | private UserState state; 8 | 9 | public User() { 10 | 11 | } 12 | public User(String mail, String firstName, String lastName, String password, String timeZone, UserState status, Address address) { 13 | 14 | } 15 | 16 | public void setAccessCode(String accessCode) { 17 | 18 | } 19 | 20 | public void setRegistrationDate(Date registrationDate) { 21 | 22 | } 23 | 24 | public void setCompany(Company company) { 25 | this.company = company; 26 | } 27 | 28 | public void setUserState(UserState userState) { 29 | this.state = userState; 30 | } 31 | 32 | public UserState getState() { 33 | return state; 34 | } 35 | 36 | public void setState(UserState state) { 37 | this.state = state; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /creation_of_objects/src/main/java/com/practicalunittesting/UserBuilder.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public class UserBuilder { 4 | private UserState state; 5 | private Company company; 6 | 7 | public static UserBuilder createUser(UserState state) { 8 | UserBuilder builder = new UserBuilder(); 9 | builder.setState(state); 10 | return builder; 11 | } 12 | 13 | public UserBuilder setState(UserState state) { 14 | this.state = state; 15 | return this; 16 | } 17 | 18 | public User create() { 19 | User user = new User(); 20 | user.setUserState(this.state); 21 | user.setCompany(this.company); 22 | return user; 23 | } 24 | 25 | public static UserBuilder createActiveUser() { 26 | return createUser(UserState.ACTIVE); 27 | } 28 | 29 | public UserBuilder withCompany(Company company) { 30 | this.company = company; 31 | return this; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /creation_of_objects/src/main/java/com/practicalunittesting/UserState.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public enum UserState { 4 | ACTIVE, NOT_VERIFIED 5 | } 6 | -------------------------------------------------------------------------------- /creation_of_objects/src/test/java/com/practicalunittesting/MockServerBuilder.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | 4 | import java.util.Map; 5 | 6 | public class MockServerBuilder { 7 | private Map responseMap; 8 | private ResponseType responseType; 9 | private String serverUrl; 10 | private boolean ssl; 11 | 12 | public MockServerBuilder withResponse(Map responseMap) { 13 | this.responseMap = responseMap; 14 | return this; 15 | } 16 | 17 | public MockServerBuilder withResponseType(ResponseType responseType) { 18 | this.responseType = responseType; 19 | return this; 20 | } 21 | 22 | public MockServerBuilder withUrl(String serverUrl) { 23 | this.serverUrl = serverUrl; 24 | return this; 25 | } 26 | 27 | public MockServerBuilder withoutSsl() { 28 | this.ssl = false; 29 | return this; 30 | } 31 | 32 | public MockServer create() { 33 | return new MockServer(responseMap, responseType, serverUrl, ssl); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /creation_of_objects/src/test/java/com/practicalunittesting/SimpleTypeTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import java.math.BigDecimal; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | 7 | public class SimpleTypeTest { 8 | 9 | List categories = Arrays.asList( 10 | product("car", new BigDecimal("100"), new BigDecimal("10000")), 11 | product("bike", new BigDecimal("20"), new BigDecimal("5000")), 12 | product("plane", new BigDecimal("1000"), new BigDecimal("500000")) 13 | ); 14 | 15 | private ProductCategory product(String name, BigDecimal discount, BigDecimal price) { 16 | return null; 17 | } 18 | 19 | List categories2 = Arrays.asList( 20 | product("car", 100, 10000), 21 | product("bike", 20, 5000), 22 | product("plane", 1000, 500000) 23 | ); 24 | 25 | private ProductCategory product(String name, int discount, int price) { 26 | return product(name, new BigDecimal(discount), new BigDecimal(price)); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /creation_of_objects/src/test/java/com/practicalunittesting/UserBuilderTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.junit.Before; 4 | import org.junit.Test; 5 | 6 | public class UserBuilderTest { 7 | 8 | private Company company; 9 | 10 | @Before 11 | public void initialize() { 12 | User notVerifiedUser = UserBuilder.createUser(UserState.NOT_VERIFIED) 13 | .create(); 14 | 15 | } 16 | 17 | @Test 18 | public void shouldCommitTransaction() { 19 | User user = UserBuilder.createActiveUser() 20 | .create(); 21 | 22 | } 23 | 24 | @Test 25 | public void shouldGetUserByCompanyData() { 26 | User user = UserBuilder.createActiveUser() 27 | .withCompany(company) 28 | .create(); 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /creation_of_objects/src/test/java/com/practicalunittesting/UserTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.joda.time.DateTime; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | import java.util.Date; 8 | 9 | public class UserTest { 10 | 11 | private Company company; 12 | private Address address; 13 | private Date oneDayAgo; 14 | 15 | @Before 16 | public void initialize() { 17 | User user = new User("email@example.com", "Example", "Example", "qwerty", 18 | "Europe/Warsaw", UserState.NOT_VERIFIED, new Address()); 19 | 20 | } 21 | 22 | @Test 23 | public void shouldCommitTransaction() { 24 | User user = new User("firstName", "lastName", "password", 25 | "email@example.com", "qwerty", UserState.ACTIVE, new Address()); 26 | DateTime oneDayAgo = new DateTime().withTimeAtStartOfDay().minusDays(1); 27 | user.setRegistrationDate(oneDayAgo.toDate()); 28 | user.setAccessCode("qwerty"); 29 | 30 | } 31 | 32 | @Test 33 | public void shouldGetUserByCompanyData() { 34 | User user = new User("email", "FirstName", "LastName", "Password", 35 | "Europe/Warsaw", UserState.ACTIVE, address); 36 | user.setRegistrationDate(new Date()); 37 | user.setCompany(company); 38 | user.setAccessCode("Access Code"); 39 | 40 | } 41 | 42 | 43 | } 44 | -------------------------------------------------------------------------------- /database_assumption/src/main/java/com/practicalunittesting/User.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public class User { 4 | } 5 | -------------------------------------------------------------------------------- /database_assumption/src/main/java/com/practicalunittesting/UserDAO.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public interface UserDAO { 4 | int getNbOfUsers(); 5 | } 6 | -------------------------------------------------------------------------------- /database_assumption/src/main/java/com/practicalunittesting/UserService.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public class UserService { 4 | public UserService(UserDAO dao) { 5 | 6 | } 7 | 8 | public void save(User user) { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /database_assumption/src/test/java/com/practicalunittesting/UserServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.assertEquals; 6 | 7 | public class UserServiceTest { 8 | 9 | private UserDAO dao; 10 | private UserService userService = new UserService(dao); 11 | 12 | @Test 13 | public void shouldAddUser() { 14 | User user = new User(); 15 | userService.save(user); 16 | assertEquals(dao.getNbOfUsers(), 1); 17 | } 18 | 19 | @Test 20 | public void shouldAddUser_Improved() { 21 | int nb = dao.getNbOfUsers(); 22 | User user = new User(); 23 | userService.save(user); 24 | assertEquals(dao.getNbOfUsers(), nb + 1); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /email/src/main/java/com/practicalunittesting/Email.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public interface Email { 4 | String PENDING = "pending"; 5 | String FAILED = "failed"; 6 | String SENT = "sent"; 7 | } 8 | -------------------------------------------------------------------------------- /email/src/main/java/com/practicalunittesting/EmailDAO.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import java.util.List; 4 | 5 | public class EmailDAO { 6 | public void removeByState(String state) { 7 | 8 | } 9 | 10 | public List findAll() { 11 | return null; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /email/src/test/java/com/practicalunittesting/EmailDAOTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.testng.annotations.Test; 4 | 5 | import static org.assertj.core.api.Assertions.assertThat; 6 | 7 | public class EmailDAOTest { 8 | 9 | private EmailDAO emailDAO; 10 | 11 | @Test 12 | public void shouldRemoveEmailsByState() { 13 | //given 14 | Email pending = createAndSaveEmail("pending","content pending", 15 | "abc@def.com", Email.PENDING); 16 | Email failed = createAndSaveEmail("failed","content failed", 17 | "abc@def.com", Email.FAILED); 18 | Email sent = createAndSaveEmail("sent","content sent", 19 | "abc@def.com", Email.SENT); 20 | 21 | //when 22 | emailDAO.removeByState(Email.FAILED); 23 | 24 | //then 25 | assertThat(emailDAO.findAll()).doesNotContain(failed); 26 | 27 | assertThat(emailDAO.findAll()) 28 | .isNotEmpty() 29 | .doesNotContain(failed); 30 | 31 | assertThat(emailDAO.findAll()) 32 | .contains(pending, sent) 33 | .doesNotContain(failed); 34 | } 35 | 36 | 37 | 38 | private Email createAndSaveEmail(String title, String content, String address, String state) { 39 | return null; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /expected_exceptions/src/main/java/com/practicalunittesting/DnsService.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public interface DnsService { 4 | void addDomainIfMissing(String address); 5 | } 6 | -------------------------------------------------------------------------------- /expected_exceptions/src/main/java/com/practicalunittesting/Domain.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public interface Domain { 4 | String getAddress(); 5 | 6 | boolean isRegisteredInDns(); 7 | 8 | int getDnsFailures(); 9 | } 10 | -------------------------------------------------------------------------------- /expected_exceptions/src/main/java/com/practicalunittesting/DomainRegistrator.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public class DomainRegistrator { 4 | 5 | private DnsService dnsService; 6 | private DomainService domainService; 7 | 8 | public void registerDomain(Domain domain) { 9 | try { 10 | dnsService.addDomainIfMissing(domain.getAddress()); 11 | } catch (RuntimeException ex) { 12 | domainService.saveDomain(domain, domain.isRegisteredInDns(), 13 | domain.getDnsFailures() + 1); 14 | throw ex; 15 | } 16 | domainService.saveDomain(domain, domain.isRegisteredInDns(), 17 | domain.getDnsFailures()); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /expected_exceptions/src/main/java/com/practicalunittesting/DomainService.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public interface DomainService { 4 | void saveDomain(Domain domain, boolean registeredInDns, int tryNb); 5 | } 6 | -------------------------------------------------------------------------------- /expected_exceptions/src/test/java/com/practicalunittesting/ExpectedExceptionsTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.junit.Test; 4 | 5 | import static com.googlecode.catchexception.CatchException.catchException; 6 | import static com.googlecode.catchexception.CatchException.caughtException; 7 | import static org.assertj.core.api.Assertions.assertThat; 8 | import static org.mockito.Mockito.doThrow; 9 | import static org.mockito.Mockito.mock; 10 | import static org.mockito.Mockito.verify; 11 | 12 | public class ExpectedExceptionsTest { 13 | 14 | private static final String DOMAIN_ADDRESS = "some.address"; 15 | private static final int DNS_FAILURES = 1; 16 | 17 | private DnsService dnsService = mock(DnsService.class); 18 | private DomainService domainService = mock(DomainService.class); 19 | private Domain domain = mock(Domain.class); 20 | private DomainRegistrator domainRegistrator = new DomainRegistrator(); 21 | 22 | @Test(expected = RuntimeException.class) 23 | public void shouldSaveFailureInformationWhenExceptionOccurWhenAddingDomain() { 24 | //given 25 | doThrow(new RuntimeException()).when(dnsService) 26 | .addDomainIfMissing(DOMAIN_ADDRESS); 27 | 28 | //when 29 | domainRegistrator.registerDomain(domain); 30 | 31 | //then 32 | verify(domainService) 33 | .saveDomain(domain, false, DNS_FAILURES + 1); 34 | } 35 | 36 | @Test 37 | public void shouldSaveFailureInformationWhenExceptionOccurWhenAddingDomainBetterVersion() { 38 | //given 39 | doThrow(new RuntimeException()).when(dnsService) 40 | .addDomainIfMissing(DOMAIN_ADDRESS); 41 | 42 | //when 43 | catchException(domainRegistrator).registerDomain(domain); 44 | 45 | //then 46 | verify(domainService) 47 | .saveDomain(domain, false, DNS_FAILURES + 1); 48 | assertThat(caughtException()).isInstanceOf(RuntimeException.class); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /fizzbuzz/src/main/java/com/practicalunittesting/FizzBuzz.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | /** 4 | * Copied from http://codereview.stackexchange.com/questions/9749/ways-to-improve-my-coding-test-fizzbuzz-solution-for-a-tdd-role 5 | */ 6 | public class FizzBuzz { 7 | 8 | private static final int MIN_VALUE = 1; 9 | private static final int MAX_VALUE = 100; 10 | 11 | public static String getResult(int input) { 12 | boolean multipleOfThree = ((input % 3) == 0); 13 | boolean multipleOfFive = ((input % 5) == 0); 14 | 15 | if (multipleOfThree && multipleOfFive) { 16 | return "FizzBuzz"; 17 | } 18 | else if (multipleOfThree) { 19 | return "Fizz"; 20 | } 21 | else if (multipleOfFive) { 22 | return "Buzz"; 23 | } 24 | return String.valueOf(input); 25 | } 26 | 27 | public static String buildOutput() { 28 | StringBuilder output = new StringBuilder(); 29 | 30 | for (int i = MIN_VALUE; i <= MAX_VALUE; i++) { 31 | output.append(getResult(i)); 32 | 33 | if (i < MAX_VALUE) { 34 | output.append(", "); 35 | } 36 | } 37 | 38 | return output.toString(); 39 | } 40 | 41 | public static final void main(String[] args) { 42 | System.out.println(buildOutput()); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /fizzbuzz/src/test/java/com/practicalunittesting/testng/FizzBuzzJUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting.testng; 2 | 3 | import com.practicalunittesting.FizzBuzz; 4 | import junitparams.JUnitParamsRunner; 5 | import junitparams.Parameters; 6 | import org.junit.Test; 7 | import org.junit.runner.RunWith; 8 | 9 | import static org.testng.Assert.assertEquals; 10 | 11 | @RunWith(JUnitParamsRunner.class) 12 | public class FizzBuzzJUnitTest { 13 | 14 | @Test 15 | @Parameters(value = {"15", "30", "75"}) 16 | public void testMultipleOfThreeAndFivePrintsFizzBuzz(int multipleOf3And5) { 17 | assertEquals("FizzBuzz", FizzBuzz.getResult(multipleOf3And5)); 18 | } 19 | 20 | @Test 21 | @Parameters(value = {"9", "36", "81"}) 22 | public void testMultipleOfThreeOnlyPrintsFizz(int multipleOf3) { 23 | assertEquals("Fizz", FizzBuzz.getResult(multipleOf3)); 24 | } 25 | 26 | @Test 27 | @Parameters(value = {"10", "55", "100"}) 28 | public void testMultipleOfFiveOnlyPrintsBuzz(int multipleOf5) { 29 | assertEquals("Buzz", FizzBuzz.getResult(multipleOf5)); 30 | } 31 | 32 | @Test 33 | @Parameters(value = {"2", "16", "23", "47", "52", "56", "67", "68", "98"}) 34 | public void testInputOfEightPrintsTheNumber(int expectedNumber) { 35 | assertEquals("" + expectedNumber, FizzBuzz.getResult(expectedNumber)); 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /fizzbuzz/src/test/java/com/practicalunittesting/testng/FizzBuzzTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting.testng; 2 | 3 | import com.practicalunittesting.FizzBuzz; 4 | import org.testng.annotations.DataProvider; 5 | import org.testng.annotations.Test; 6 | 7 | import static org.testng.Assert.*; 8 | 9 | @Test 10 | public class FizzBuzzTest { 11 | 12 | @DataProvider 13 | public static Integer[][] multipleOf3And5() { 14 | return new Integer[][]{{15}, {30}, {75}}; 15 | } 16 | 17 | @Test(dataProvider = "multipleOf3And5") 18 | public void testMultipleOfThreeAndFivePrintsFizzBuzz(int multipleOf3And5) { 19 | assertEquals("FizzBuzz", FizzBuzz.getResult(multipleOf3And5)); 20 | } 21 | 22 | @DataProvider 23 | public static Integer[][] multipleOf3() { 24 | return new Integer[][]{{9}, {36}, {81}}; 25 | } 26 | 27 | @Test(dataProvider = "multipleOf3") 28 | public void testMultipleOfThreeOnlyPrintsFizz(int multipleOf3) { 29 | assertEquals("Fizz", FizzBuzz.getResult(multipleOf3)); 30 | } 31 | 32 | @DataProvider 33 | private static final Object[][] multipleOf5(){ 34 | return new Object[][] {{10}, {40}, {100}}; 35 | } 36 | 37 | @Test(dataProvider = "multipleOf5") 38 | public void testMultipleOfFiveOnlyPrintsBuzz(int multipleOf5) { 39 | assertEquals("Buzz", FizzBuzz.getResult(multipleOf5)); 40 | } 41 | 42 | @DataProvider 43 | private static final Object[][] numbers(){ 44 | return new Object[][] {{2}, {16}, {23}, {47}, {52}, {56}, {67}, {68}, {98}}; 45 | } 46 | 47 | @Test(dataProvider = "numbers") 48 | public void testInputOfEightPrintsTheNumber(int expectedNumber) { 49 | assertEquals("" + expectedNumber, FizzBuzz.getResult(expectedNumber)); 50 | } 51 | } 52 | 53 | -------------------------------------------------------------------------------- /fizzbuzz_original/src/main/java/com/practicalunittesting/FizzBuzz.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | /** 4 | * Copied from http://codereview.stackexchange.com/questions/9749/ways-to-improve-my-coding-test-fizzbuzz-solution-for-a-tdd-role 5 | */ 6 | public class FizzBuzz { 7 | 8 | private static final int MIN_VALUE = 1; 9 | private static final int MAX_VALUE = 100; 10 | 11 | public static String getResult(int input) { 12 | boolean multipleOfThree = ((input % 3) == 0); 13 | boolean multipleOfFive = ((input % 5) == 0); 14 | 15 | if (multipleOfThree && multipleOfFive) { 16 | return "FizzBuzz"; 17 | } 18 | else if (multipleOfThree) { 19 | return "Fizz"; 20 | } 21 | else if (multipleOfFive) { 22 | return "Buzz"; 23 | } 24 | return String.valueOf(input); 25 | } 26 | 27 | public static String buildOutput() { 28 | StringBuilder output = new StringBuilder(); 29 | 30 | for (int i = MIN_VALUE; i <= MAX_VALUE; i++) { 31 | output.append(getResult(i)); 32 | 33 | if (i < MAX_VALUE) { 34 | output.append(", "); 35 | } 36 | } 37 | 38 | return output.toString(); 39 | } 40 | 41 | public static final void main(String[] args) { 42 | System.out.println(buildOutput()); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /fizzbuzz_original/src/test/java/com/practicalunittesting/FizzBuzzTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import com.practicalunittesting.FizzBuzz; 4 | import org.junit.Assert; 5 | import org.junit.Test; 6 | 7 | import static org.junit.Assert.assertEquals; 8 | import static org.junit.Assert.assertNotNull; 9 | import static org.junit.Assert.assertNotSame; 10 | 11 | /** 12 | * Copied from: http://codereview.stackexchange.com/questions/9749/ways-to-improve-my-coding-test-fizzbuzz-solution-for-a-tdd-role 13 | */ 14 | public class FizzBuzzTest { 15 | 16 | @Test 17 | public void testMultipleOfThreeAndFivePrintsFizzBuzz() { 18 | Assert.assertEquals("FizzBuzz", FizzBuzz.getResult(15)); 19 | } 20 | 21 | @Test 22 | public void testMultipleOfThreeOnlyPrintsFizz() { 23 | assertEquals("Fizz", FizzBuzz.getResult(93)); 24 | } 25 | 26 | @Test 27 | public void testMultipleOfFiveOnlyPrintsBuzz() { 28 | assertEquals("Buzz", FizzBuzz.getResult(10)); 29 | } 30 | 31 | @Test 32 | public void testInputOfEightPrintsTheNumber() { 33 | assertEquals("8", FizzBuzz.getResult(8)); 34 | } 35 | } -------------------------------------------------------------------------------- /form/src/main/java/com/practicalunittesting/Form.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public class Form { 4 | private boolean updateAllowed; 5 | 6 | public boolean isUpdateAllowed() { 7 | return updateAllowed; 8 | } 9 | 10 | public void setUpdateAllowed(boolean updateAllowed) { 11 | this.updateAllowed = updateAllowed; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /form/src/test/java/com/practicalunittesting/FormTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.mockito.Mockito; 4 | import org.testng.annotations.Test; 5 | 6 | import static org.testng.Assert.assertTrue; 7 | 8 | public class FormTest { 9 | 10 | @Test 11 | public void testFormUpdate() { 12 | // given 13 | Form f = Mockito.mock(Form.class); 14 | Mockito.when(f.isUpdateAllowed()).thenReturn(true); 15 | 16 | // when 17 | boolean result = f.isUpdateAllowed(); 18 | 19 | // then 20 | assertTrue(result); 21 | } 22 | 23 | @Test 24 | public void testFormUpdateWithoutMocks() { 25 | // given 26 | Form f = new Form(); 27 | f.setUpdateAllowed(true); 28 | 29 | // when - then 30 | assertTrue(f.isUpdateAllowed()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /global_state/src/main/java/com/practicalunittesting/BaseServletContextListener.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public class BaseServletContextListener { 4 | public BaseServletContextListener(LoggingPropertyConfigurator configurator) { 5 | 6 | } 7 | 8 | public void contextInitialized(Object o) { 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /global_state/src/main/java/com/practicalunittesting/LoggingInitialisationException.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public class LoggingInitialisationException extends Throwable { 4 | } 5 | -------------------------------------------------------------------------------- /global_state/src/main/java/com/practicalunittesting/LoggingPropertyConfigurator.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import java.util.Properties; 4 | 5 | public interface LoggingPropertyConfigurator { 6 | void configure(Properties properties); 7 | } 8 | -------------------------------------------------------------------------------- /global_state/src/test/java/com/practicalunittesting/FlickeringTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.Properties; 6 | 7 | import static org.mockito.Matchers.any; 8 | import static org.mockito.Mockito.mock; 9 | import static org.mockito.Mockito.verify; 10 | 11 | public class FlickeringTest { 12 | 13 | LoggingPropertyConfigurator configurator 14 | = mock(LoggingPropertyConfigurator.class); 15 | BaseServletContextListener baseServletContextListener 16 | = new BaseServletContextListener(configurator); 17 | 18 | @Test 19 | public void shouldLoadDefaultProperties() { 20 | baseServletContextListener.contextInitialized(null); 21 | verify(configurator).configure(any(Properties.class)); 22 | } 23 | 24 | @Test(expected = LoggingInitialisationException.class) 25 | public void shouldThrowLoggingException() { 26 | System.setProperty("logConfig", "nonExistingFile"); 27 | baseServletContextListener.contextInitialized(null); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /global_state/src/test/java/com/practicalunittesting/NoLongerFlickeringTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.junit.Before; 4 | import org.junit.Test; 5 | import org.testng.annotations.BeforeMethod; 6 | 7 | import java.util.Properties; 8 | 9 | import static org.mockito.Matchers.any; 10 | import static org.mockito.Mockito.mock; 11 | import static org.mockito.Mockito.verify; 12 | 13 | public class NoLongerFlickeringTest { 14 | 15 | LoggingPropertyConfigurator configurator 16 | = mock(LoggingPropertyConfigurator.class); 17 | BaseServletContextListener baseServletContextListener 18 | = new BaseServletContextListener(configurator); 19 | 20 | @Before 21 | public void cleanSystemProperties() { 22 | System.setProperty("logConfig", null); 23 | } 24 | 25 | @Test 26 | public void shouldLoadDefaultProperties() { 27 | baseServletContextListener.contextInitialized(null); 28 | verify(configurator).configure(any(Properties.class)); 29 | } 30 | 31 | @Test(expected = LoggingInitialisationException.class) 32 | public void shouldThrowLoggingException() { 33 | System.setProperty("logConfig", "nonExistingFile"); 34 | baseServletContextListener.contextInitialized(null); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /localized_exceptions/src/main/java/com/practicalunittesting/MaliciousMyList.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public class MaliciousMyList { 4 | 5 | public MaliciousMyList() { 6 | throw new IndexOutOfBoundsException(); 7 | } 8 | 9 | public void add(T i) { 10 | } 11 | 12 | public T get(T i) { 13 | return null; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /localized_exceptions/src/main/java/com/practicalunittesting/MyList.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class MyList { 7 | private List list; 8 | 9 | public MyList() { 10 | this.list = new ArrayList(); 11 | } 12 | 13 | public void add(E e) { 14 | list.add(e); 15 | } 16 | 17 | public E get(int i) { 18 | return list.get(i); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /localized_exceptions/src/test/java/com/practicalunittesting/MaliciousMyListTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.assertTrue; 6 | 7 | public class MaliciousMyListTest { 8 | 9 | @Test(expected=IndexOutOfBoundsException.class) 10 | public void testMyList() { 11 | MaliciousMyList list = new MaliciousMyList(); 12 | list.add(1); 13 | list.add(2); 14 | list.add(3); 15 | list.add(3); 16 | list.add(4); 17 | assertTrue(4 == list.get(4)); 18 | assertTrue(2 == list.get(1)); 19 | assertTrue(3 == list.get(2)); 20 | 21 | list.get(6); 22 | } 23 | 24 | 25 | @Test(expected=IndexOutOfBoundsException.class) 26 | public void testNegative() { 27 | MaliciousMyList list = new MaliciousMyList(); 28 | list.add(1); 29 | list.add(2); 30 | list.add(3); 31 | list.add(3); 32 | list.add(4); 33 | list.get(-1); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /localized_exceptions/src/test/java/com/practicalunittesting/updated/MyListCatchExceptionTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting.updated; 2 | 3 | import com.practicalunittesting.MyList; 4 | import org.junit.Test; 5 | 6 | import static com.googlecode.catchexception.CatchException.catchException; 7 | import static com.googlecode.catchexception.CatchException.caughtException; 8 | import static org.assertj.core.api.Assertions.assertThat; 9 | 10 | public class MyListCatchExceptionTest { 11 | 12 | @Test 13 | public void shouldThrowExceptionWhenTryingToGetElementOutsideTheList() { 14 | MyList list = new MyList(); 15 | list.add(0); 16 | list.add(1); 17 | list.add(2); 18 | catchException(list).get(3); 19 | 20 | assertThat(caughtException()).isExactlyInstanceOf(IndexOutOfBoundsException.class); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /localized_exceptions/src/test/java/com/practicalunittesting/updated/MyListTryCatchFestAssertTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting.updated; 2 | 3 | import com.practicalunittesting.MyList; 4 | import org.junit.Test; 5 | 6 | import static org.assertj.core.api.Assertions.assertThat; 7 | import static org.junit.Assert.fail; 8 | 9 | public class MyListTryCatchFestAssertTest { 10 | 11 | @Test 12 | public void shouldThrowExceptionWhenTryingToGetElementOutsideTheList() { 13 | MyList list = new MyList(); 14 | list.add(0); 15 | list.add(1); 16 | list.add(2); 17 | try { 18 | list.get(3); 19 | fail("Expected IndexOutOfBoundsException but none has been thrown!"); 20 | } 21 | catch(Exception e) {; 22 | assertThat(e).isInstanceOf(IndexOutOfBoundsException.class).hasNoCause(); 23 | assertThat(e.getMessage()).contains("Index: 3").contains("Size: 3"); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /localized_exceptions/src/test/java/com/practicalunittesting/updated/MyListTryCatchTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting.updated; 2 | 3 | import com.practicalunittesting.MyList; 4 | import org.junit.Test; 5 | 6 | import static org.assertj.core.api.Assertions.assertThat; 7 | import static org.junit.Assert.fail; 8 | 9 | public class MyListTryCatchTest { 10 | 11 | @Test 12 | public void shouldThrowExceptionWhenTryingToGetElementOutsideTheList() { 13 | MyList list = new MyList(); 14 | list.add(0); 15 | list.add(1); 16 | list.add(2); 17 | try { 18 | list.get(3); 19 | fail("Expected IndexOutOfBoundsException but none has been thrown!"); 20 | } 21 | catch(IndexOutOfBoundsException ioobe) { 22 | // fine, this is what we wanted 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /mock_counter/src/main/java/com/practicalunittesting/City.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public class City { 4 | public City(District district, Object bid) { 5 | } 6 | 7 | public boolean isLocatedIn(District otherDistrict) { 8 | return false; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /mock_counter/src/main/java/com/practicalunittesting/District.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public interface District { 4 | } 5 | -------------------------------------------------------------------------------- /mock_counter/src/test/java/com/practicalunittesting/CityTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.testng.annotations.Test; 4 | 5 | import static org.assertj.core.api.Assertions.assertThat; 6 | import static org.mockito.Mockito.mock; 7 | 8 | public class CityTest { 9 | 10 | private static final double NUMBER_OF_PEOPLE = 1.2345d; 11 | 12 | @Test 13 | public void shouldRecognizeDistrict() { 14 | //given 15 | District district = mock(District.class); 16 | District anotherDistrict = mock(District.class); 17 | 18 | //when 19 | City city = new City(district, NUMBER_OF_PEOPLE); 20 | 21 | //then 22 | assertThat(city.isLocatedIn(district)).isTrue(); 23 | assertThat(city.isLocatedIn(anotherDistrict)).isFalse(); 24 | } 25 | 26 | @Test 27 | public void shouldRecognizeItsDistrict() { 28 | //given 29 | District district = mock(District.class); 30 | 31 | //when 32 | City city = new City(district, NUMBER_OF_PEOPLE); 33 | 34 | //then 35 | assertThat(city.isLocatedIn(district)).isTrue(); 36 | } 37 | 38 | @Test 39 | public void shouldRecognizeDifferentDistrict() { 40 | //given 41 | District district = mock(District.class); 42 | District anotherDistrict = mock(District.class); 43 | 44 | //when 45 | City city = new City(district, NUMBER_OF_PEOPLE); 46 | 47 | //then 48 | assertThat(city.isLocatedIn(anotherDistrict)).isFalse(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /mocking_container/src/main/java/com/practicalunittesting/Context.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public interface Context { 4 | String getTimezone(); 5 | } 6 | -------------------------------------------------------------------------------- /mocking_container/src/main/java/com/practicalunittesting/UserDataInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.springframework.web.servlet.ModelAndView; 4 | 5 | public class UserDataInterceptor { 6 | public UserDataInterceptor(Context context) { 7 | } 8 | 9 | public void postHandle(Object o, Object o1, Object o2, ModelAndView modelAndView) { 10 | 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /mocking_container/src/test/java/com/practicalunittesting/MockingContainerTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.springframework.web.servlet.ModelAndView; 4 | import org.testng.annotations.Test; 5 | 6 | import static org.mockito.BDDMockito.given; 7 | import static org.mockito.Mockito.mock; 8 | import static org.mockito.Mockito.verify; 9 | 10 | public class MockingContainerTest { 11 | 12 | @Test 13 | public void shouldAddTimeZoneToModelAndView() { 14 | //given 15 | Context context = mock(Context.class); 16 | ModelAndView modelAndView = mock(ModelAndView.class); 17 | given(context.getTimezone()).willReturn("timezone X"); 18 | 19 | //when 20 | new UserDataInterceptor(context) 21 | .postHandle(null, null, null, modelAndView); 22 | 23 | //then 24 | verify(modelAndView).addObject("timezone", "timezone X"); 25 | } 26 | 27 | @Test 28 | public void shouldAddTimeZoneToModelAndView_Improved() { 29 | //given 30 | Context context = mock(Context.class); 31 | ModelAndView modelAndView = new ModelAndView(); 32 | given(context.getTimezone()).willReturn("timezone X"); 33 | 34 | //when 35 | new UserDataInterceptor(context) 36 | .postHandle(null, null, null, modelAndView); 37 | 38 | //then 39 | //assertThat(modelAndView).contains("timezone", "timezone X"); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /mocks_are_good/src/main/java/com/practicalunittesting/Report.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import java.math.BigDecimal; 4 | 5 | public class Report { 6 | public Report(Object o, String s, int i, int i1, int i2, BigDecimal one, BigDecimal one1, int i3) { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /mocks_are_good/src/main/java/com/practicalunittesting/TrafficService.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public class TrafficService { 4 | private TrafficTrend trafficTrend; 5 | 6 | public TrafficService(TrafficTrendProvider trafficTrendProvider) { 7 | 8 | } 9 | 10 | public TrafficTrend getTrafficTrend() { 11 | return trafficTrend; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /mocks_are_good/src/main/java/com/practicalunittesting/TrafficTrend.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import java.util.Date; 4 | 5 | public class TrafficTrend { 6 | public TrafficTrend(Report report, Report report1, Date date, Date date1, Date date2, Date date3) { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /mocks_are_good/src/main/java/com/practicalunittesting/TrafficTrendProvider.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public interface TrafficTrendProvider { 4 | TrafficTrend getTrafficTrend(); 5 | } 6 | -------------------------------------------------------------------------------- /mocks_are_good/src/test/java/com/practicalunittesting/TrafficTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.junit.Test; 4 | 5 | import java.math.BigDecimal; 6 | import java.util.Date; 7 | 8 | import static org.assertj.core.api.Assertions.assertThat; 9 | import static org.mockito.BDDMockito.given; 10 | import static org.mockito.Mockito.mock; 11 | 12 | public class TrafficTest { 13 | 14 | @Test 15 | public void shouldGetTrafficTrend() { 16 | //given 17 | TrafficTrendProvider trafficTrendProvider 18 | = mock(TrafficTrendProvider.class); 19 | Report report = new Report(null, "", 1, 2, 3, 20 | BigDecimal.ONE, BigDecimal.ONE, 1); 21 | TrafficTrend trafficTrend = new TrafficTrend(report, report, 22 | new Date(), new Date(), new Date(), new Date()); 23 | given(trafficTrendProvider.getTrafficTrend()).willReturn(trafficTrend); 24 | TrafficService service = new TrafficService(trafficTrendProvider); 25 | 26 | //when 27 | TrafficTrend result = service.getTrafficTrend(); 28 | 29 | //then 30 | assertThat(result).isEqualTo(trafficTrend); 31 | } 32 | 33 | @Test 34 | public void shouldGetTrafficTrend_UsingMocks() { 35 | //given 36 | TrafficTrendProvider trafficTrendProvider 37 | = mock(TrafficTrendProvider.class); 38 | TrafficTrend trafficTrend = mock(TrafficTrend.class); 39 | given(trafficTrendProvider.getTrafficTrend()).willReturn(trafficTrend); 40 | TrafficService service = new TrafficService(trafficTrendProvider); 41 | 42 | //when 43 | TrafficTrend result = service.getTrafficTrend(); 44 | 45 | //then 46 | assertThat(result).isEqualTo(trafficTrend); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /no_assertions/src/test/java/com/practicalunittesting/Format.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public interface Format { 4 | IResult execute(); 5 | } 6 | -------------------------------------------------------------------------------- /no_assertions/src/test/java/com/practicalunittesting/IResult.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import java.util.Iterator; 4 | 5 | public interface IResult { 6 | Iterator iterator(); 7 | 8 | String getMessage(); 9 | 10 | int size(); 11 | } 12 | -------------------------------------------------------------------------------- /no_assertions/src/test/java/com/practicalunittesting/NoAssertionsTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.testng.annotations.Test; 4 | 5 | import java.util.Iterator; 6 | import java.util.concurrent.Executor; 7 | 8 | import static org.assertj.core.api.Assertions.assertThat; 9 | 10 | public class NoAssertionsTest { 11 | 12 | Format format = null; 13 | 14 | @Test 15 | public void originalTest() { 16 | IResult result = format.execute(); 17 | System.out.println(result.size()); 18 | Iterator iter = result.iterator(); 19 | while (iter.hasNext()) { 20 | IResult r = (IResult) iter.next(); 21 | System.out.println(r.getMessage()); 22 | } 23 | } 24 | 25 | @Test 26 | public void betterVersion() { 27 | IResult result = format.execute(); 28 | assertThat(result.size()).isEqualTo(3); 29 | Iterator iter = result.iterator(); 30 | while (iter.hasNext()) { 31 | IResult r = (IResult) iter.next(); 32 | assertThat(r.getMessage()).contains("error"); 33 | } 34 | 35 | } 36 | } -------------------------------------------------------------------------------- /object123/src/main/java/com/practicalunittesting/DaoTestHelper.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public interface DaoTestHelper { 4 | User addUserAndAssociateWithProduct(Product product, long whatever, ProductUserState state); 5 | 6 | void userProduct30DayStatistics(User user, String language, int whatever); 7 | } 8 | -------------------------------------------------------------------------------- /object123/src/main/java/com/practicalunittesting/Product.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public interface Product { 4 | } 5 | -------------------------------------------------------------------------------- /object123/src/main/java/com/practicalunittesting/ProductUserState.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public enum ProductUserState { 4 | ACTIVE, DELETED; 5 | } 6 | -------------------------------------------------------------------------------- /object123/src/main/java/com/practicalunittesting/User.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public interface User { 4 | } 5 | -------------------------------------------------------------------------------- /object123/src/test/java/com/practicalunittesting/ImportantTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.testng.annotations.Test; 4 | 5 | public class ImportantTest { 6 | 7 | private DaoTestHelper daoTestHelper; 8 | private Product product; 9 | 10 | @Test 11 | public void importantTest() { 12 | User user1 = daoTestHelper.addUserAndAssociateWithProduct( 13 | product, 30l, ProductUserState.ACTIVE); 14 | daoTestHelper.userProduct30DayStatistics(user1, "PL", 1); 15 | daoTestHelper.userProduct30DayStatistics(user1, "US", 2); 16 | User user2 = daoTestHelper.addUserAndAssociateWithProduct( 17 | product, 30l, ProductUserState.ACTIVE); 18 | daoTestHelper.userProduct30DayStatistics(user2, "PL", 4); 19 | daoTestHelper.userProduct30DayStatistics(user2, "US", 8); 20 | 21 | // ... and so on till user5 or so 22 | } 23 | 24 | @Test 25 | public void renamedTest() { 26 | User userWith1PlEntry = daoTestHelper.addUserAndAssociateWithProduct( 27 | product, 30l, ProductUserState.ACTIVE); 28 | daoTestHelper.userProduct30DayStatistics(userWith1PlEntry, "PL", 1); 29 | daoTestHelper.userProduct30DayStatistics(userWith1PlEntry, "US", 2); 30 | User userWith4PlEntries = daoTestHelper.addUserAndAssociateWithProduct( 31 | product, 30l, ProductUserState.ACTIVE); 32 | daoTestHelper.userProduct30DayStatistics(userWith4PlEntries, "PL", 4); 33 | daoTestHelper.userProduct30DayStatistics(userWith4PlEntries, "US", 8); 34 | } 35 | 36 | @Test 37 | public void longTest() { 38 | User user1 = daoTestHelper.addUserAndAssociateWithProduct( 39 | product, 30l, ProductUserState.ACTIVE); 40 | daoTestHelper.userProduct30DayStatistics(user1, "PL", 1); 41 | daoTestHelper.userProduct30DayStatistics(user1, "US", 2); 42 | User user2 = daoTestHelper.addUserAndAssociateWithProduct( 43 | product, 30l, ProductUserState.ACTIVE); 44 | daoTestHelper.userProduct30DayStatistics(user2, "PL", 4); 45 | daoTestHelper.userProduct30DayStatistics(user2, "US", 8); 46 | User user3 = daoTestHelper.addUserAndAssociateWithProduct( 47 | product, 30l, ProductUserState.DELETED); 48 | daoTestHelper.userProduct30DayStatistics(user3, "PL", 16); 49 | daoTestHelper.userProduct30DayStatistics(user3, "CZ", 32); 50 | User user4 = daoTestHelper.addUserAndAssociateWithProduct( 51 | product, 30l, ProductUserState.ACTIVE); 52 | daoTestHelper.userProduct30DayStatistics(user3, "US", 64); 53 | User user5 = daoTestHelper.addUserAndAssociateWithProduct( 54 | product, 30l, ProductUserState.DELETED); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /pager/src/main/java/com/practicalunittesting/Pager.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import java.math.BigDecimal; 4 | 5 | public class Pager { 6 | private final int perPage; 7 | private int offset; 8 | 9 | public Pager(int perPage) { 10 | this.perPage = perPage; 11 | this.offset = 0; 12 | } 13 | 14 | public void goToNextPage() { 15 | this.offset = +perPage; 16 | } 17 | 18 | public int getOffset() { 19 | return offset; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /pager/src/test/java/com/practicalunittesting/PagerTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.testng.annotations.Test; 4 | 5 | import static org.assertj.core.api.Assertions.assertThat; 6 | 7 | @Test 8 | public class PagerTest { 9 | 10 | private static final int PER_PAGE = 10; 11 | 12 | public void shouldGiveOffsetZeroWhenOnZeroPage() { 13 | Pager pager = new Pager(PER_PAGE); 14 | 15 | assertThat(pager.getOffset()).isEqualTo(0); 16 | } 17 | 18 | public void shouldIncreaseOffsetWhenGoingToPageOne() { 19 | Pager pager = new Pager(PER_PAGE); 20 | 21 | pager.goToNextPage(); 22 | 23 | assertThat(pager.getOffset()).isEqualTo(PER_PAGE); 24 | } 25 | 26 | public void shouldIncreaseOffsetWhenGoingToPageTwo() { 27 | Pager pager = new Pager(PER_PAGE); 28 | 29 | pager.goToNextPage(); 30 | pager.goToNextPage(); 31 | 32 | assertThat(pager.getOffset()).isEqualTo(2 * PER_PAGE); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /printwriter/src/main/java/com/practicalunittesting/Filter.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public interface Filter { 4 | } 5 | -------------------------------------------------------------------------------- /printwriter/src/main/java/com/practicalunittesting/ReportController.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.stereotype.Controller; 5 | 6 | import javax.servlet.ServletException; 7 | import javax.servlet.http.HttpServlet; 8 | import javax.servlet.http.HttpServletRequest; 9 | import javax.servlet.http.HttpServletResponse; 10 | import java.io.IOException; 11 | import java.io.PrintWriter; 12 | import java.util.List; 13 | 14 | @Controller 15 | public class ReportController { 16 | 17 | private final ReportService reportService; 18 | 19 | @Autowired 20 | public ReportController(ReportService reportService) { 21 | this.reportService = reportService; 22 | } 23 | 24 | public void generateReport(HttpServletRequest request, 25 | HttpServletResponse response) throws IOException { 26 | Filter filter = parseRequest(request); 27 | List reportData = reportService.getReportData(filter); 28 | PrintWriter writer = response.getWriter(); 29 | writeHeaders(writer); 30 | for (ReportData data : reportData) { 31 | writer.append(String.valueOf(data.getMin())); 32 | writer.append(","); 33 | writer.append(String.valueOf(data.getMax())); 34 | writer.append(","); 35 | writer.append(String.valueOf(data.getAvg())); 36 | writer.append("\n"); 37 | } 38 | } 39 | 40 | private void writeHeaders(PrintWriter writer) { 41 | writer.append("min,max,avg\n"); 42 | } 43 | 44 | private Filter parseRequest(HttpServletRequest request) { 45 | return new Filter() {}; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /printwriter/src/main/java/com/practicalunittesting/ReportData.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public class ReportData { 4 | 5 | private final int min; 6 | private final int max; 7 | private final double avg; 8 | 9 | public ReportData(int min, int max, double avg) { 10 | this.min = min; 11 | this.max = max; 12 | this.avg = avg; 13 | } 14 | 15 | public int getMin() { 16 | return min; 17 | } 18 | 19 | public int getMax() { 20 | return max; 21 | } 22 | 23 | public double getAvg() { 24 | return avg; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /printwriter/src/main/java/com/practicalunittesting/ReportService.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import java.util.List; 4 | 5 | public interface ReportService { 6 | List getReportData(Filter filter); 7 | } 8 | -------------------------------------------------------------------------------- /printwriter/src/test/java/com/practicalunittesting/ControllerTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.mockito.InOrder; 4 | import org.mockito.Mockito; 5 | import org.testng.annotations.Test; 6 | 7 | import javax.servlet.http.HttpServletRequest; 8 | import javax.servlet.http.HttpServletResponse; 9 | 10 | import java.io.IOException; 11 | import java.io.PrintWriter; 12 | import java.util.Arrays; 13 | 14 | import static org.mockito.BDDMockito.given; 15 | import static org.mockito.Matchers.any; 16 | import static org.mockito.Matchers.refEq; 17 | import static org.mockito.Mockito.mock; 18 | import static org.mockito.Mockito.verify; 19 | 20 | public class ControllerTest { 21 | 22 | HttpServletRequest req = mock(HttpServletRequest.class); 23 | HttpServletResponse resp = mock(HttpServletResponse.class); 24 | ReportService reportService = mock(ReportService.class); 25 | PrintWriter writer = mock(PrintWriter.class); 26 | 27 | ReportController ctrl = new ReportController(reportService); 28 | 29 | @Test 30 | public void shouldWriteReportData() throws IOException { 31 | // given 32 | ReportData dataPl = new ReportData(1, 2, 1.5); 33 | ReportData dataFr = new ReportData(3, 4, 0.12345); 34 | 35 | given(resp.getWriter()).willReturn(writer); 36 | given(reportService.getReportData(any(Filter.class))) 37 | .willReturn(Arrays.asList(dataPl, dataFr)); 38 | 39 | // when 40 | ctrl.generateReport(req, resp); 41 | 42 | // then 43 | InOrder inOrder = Mockito.inOrder(writer); 44 | inOrder.verify(writer).append("min,max,avg\n"); 45 | 46 | inOrder.verify(writer).append(String.valueOf(1)); 47 | inOrder.verify(writer).append(","); 48 | inOrder.verify(writer).append(String.valueOf(2)); 49 | inOrder.verify(writer).append(","); 50 | inOrder.verify(writer).append(String.valueOf(1.5)); 51 | inOrder.verify(writer).append("\n"); 52 | inOrder.verify(writer).append(String.valueOf(3)); 53 | inOrder.verify(writer).append(","); 54 | inOrder.verify(writer).append(String.valueOf(4)); 55 | inOrder.verify(writer).append(","); 56 | inOrder.verify(writer).append(String.valueOf(0.12345)); 57 | inOrder.verify(writer).append("\n"); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /printwriter/src/test/java/com/practicalunittesting/ControllerWithStringWriterTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.testng.annotations.Test; 4 | 5 | import javax.servlet.http.HttpServletRequest; 6 | import javax.servlet.http.HttpServletResponse; 7 | import java.io.IOException; 8 | import java.io.PrintWriter; 9 | import java.io.StringWriter; 10 | import java.io.Writer; 11 | import java.util.Arrays; 12 | 13 | import static org.assertj.core.api.Assertions.assertThat; 14 | import static org.mockito.BDDMockito.given; 15 | import static org.mockito.Matchers.any; 16 | import static org.mockito.Mockito.mock; 17 | 18 | public class ControllerWithStringWriterTest { 19 | 20 | HttpServletRequest req = mock(HttpServletRequest.class); 21 | HttpServletResponse resp = mock(HttpServletResponse.class); 22 | ReportService reportService = mock(ReportService.class); 23 | 24 | ReportController ctrl = new ReportController(reportService); 25 | 26 | @Test 27 | public void shouldWriteReportData() throws IOException { 28 | // given 29 | ReportData dataPl = new ReportData(1, 2, 1.5); 30 | ReportData dataFr = new ReportData(3, 4, 0.12345); 31 | 32 | Writer stringWriter = new StringWriter(); 33 | PrintWriter writer = new PrintWriter(stringWriter); 34 | given(resp.getWriter()).willReturn(writer); 35 | given(reportService.getReportData(any(Filter.class))) 36 | .willReturn(Arrays.asList(dataPl, dataFr)); 37 | 38 | // when 39 | ctrl.generateReport(req, resp); 40 | 41 | // then 42 | assertThat(stringWriter.toString()) 43 | .isEqualTo("min,max,avg\n1,2,1.5\n3,4,0.12345\n"); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /self_test/src/main/java/com/practicalunittesting/PaymentMethod.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import java.util.List; 4 | 5 | import com.google.common.collect.Lists; 6 | 7 | public enum PaymentMethod { 8 | 9 | VISA, MASTERCARD, BANK_TRANSFER; 10 | 11 | public boolean isEligibleForCountry(String country) { 12 | return false; 13 | } 14 | 15 | public static List getMethodsForCountry( 16 | String country, List availableMethods) { 17 | List methodsForCountry = Lists.newArrayList(); 18 | for (PaymentMethod method : availableMethods) { 19 | if (method.isEligibleForCountry(country)) { 20 | methodsForCountry.add(method); 21 | } 22 | } 23 | return methodsForCountry; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /self_test/src/test/java/com/practicalunittesting/PaymentMethodTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import com.google.common.collect.Lists; 4 | import org.testng.annotations.Test; 5 | 6 | import java.util.Arrays; 7 | import java.util.List; 8 | 9 | import static org.assertj.core.api.Assertions.assertThat; 10 | 11 | public class PaymentMethodTest { 12 | 13 | @Test 14 | public void shouldGetMethodsForPoland() { 15 | //given 16 | List all = Lists.newArrayList(PaymentMethod.values()); 17 | List methodsAvailableInPoland = Lists.newArrayList(); 18 | for (PaymentMethod method : all) { 19 | if (method.isEligibleForCountry("PL")) { 20 | methodsAvailableInPoland.add(method); 21 | } 22 | } 23 | 24 | //when 25 | List methodsForCountry = PaymentMethod 26 | .getMethodsForCountry("PL", all); 27 | 28 | //then 29 | assertThat(methodsForCountry).isEqualTo(methodsAvailableInPoland); 30 | } 31 | 32 | @Test 33 | public void shouldGetMethodsForPolandImproved() { 34 | //given 35 | List all = Lists.newArrayList(PaymentMethod.values()); 36 | List methodsAvailableInPoland = Arrays.asList( 37 | new PaymentMethod[]{ 38 | PaymentMethod.MASTERCARD, 39 | PaymentMethod.VISA 40 | // and all other methods available in Poland 41 | }); 42 | 43 | //when 44 | List methodsForCountry = PaymentMethod 45 | .getMethodsForCountry("PL", all); 46 | 47 | //then 48 | assertThat(methodsForCountry).isEqualTo(methodsAvailableInPoland); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include 'localized_exceptions', 2 | 'asserting_private_methods', 3 | 'what_is_asserted', 4 | 'change_test_after_logic_is_changed', 5 | 'fizzbuzz', 6 | 'fizzbuzz_original', 7 | 'true_false', 8 | 'builders', 9 | 'pager', 10 | 'printwriter', 11 | 'mock_counter', 12 | 'object123', 13 | 'zeros_are_evil', 14 | 'no_assertions', 15 | 'autogeneration', 16 | 'smart_values', 17 | 'self_test', 18 | 'email', 19 | 'form', 20 | 'expected_exceptions', 21 | 'verify_never', 22 | 'mocking_container', 23 | 'global_state', 24 | 'database_assumption', 25 | 'time_means_trouble', 26 | 'waste_of_time', 27 | 'copy_and_paste', 28 | 'valid_and_not_valid', 29 | 'test_behaviour', 30 | 'ceremony', 31 | 'creation_of_objects', 32 | 'mocks_are_good' 33 | -------------------------------------------------------------------------------- /smart_values/src/main/java/com/practicalunittesting/PriceCalculator.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import java.math.BigDecimal; 4 | 5 | 6 | public class PriceCalculator { 7 | public PriceCalculator(BigDecimal minMargin, BigDecimal maxMargin, BigDecimal premiumShare) { 8 | 9 | } 10 | } -------------------------------------------------------------------------------- /smart_values/src/main/java/com/practicalunittesting/PriceCalculatorFactory.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import java.math.BigDecimal; 4 | 5 | public class PriceCalculatorFactory { 6 | 7 | private SettingsService settingsService; 8 | 9 | public PriceCalculatorFactory(SettingsService settings) { 10 | 11 | } 12 | 13 | public PriceCalculator create() { 14 | BigDecimal minMargin = settingsService.getMinMargin(); 15 | BigDecimal maxMargin = settingsService.getMaxMargin(); 16 | BigDecimal premiumShare = settingsService.getPremiumShare(); 17 | return new PriceCalculator(minMargin, maxMargin, premiumShare); 18 | } 19 | } -------------------------------------------------------------------------------- /smart_values/src/main/java/com/practicalunittesting/SettingsService.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import java.math.BigDecimal; 4 | 5 | public interface SettingsService { 6 | BigDecimal getMinMargin(); 7 | 8 | BigDecimal getMaxMargin(); 9 | 10 | BigDecimal getPremiumShare(); 11 | } 12 | -------------------------------------------------------------------------------- /smart_values/src/test/java/com/practicalunittesting/ImprovedPriceCalculatorFactoryTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.testng.annotations.Test; 4 | 5 | import java.math.BigDecimal; 6 | 7 | import static org.assertj.core.api.Assertions.assertThat; 8 | import static org.mockito.BDDMockito.given; 9 | import static org.mockito.Mockito.mock; 10 | 11 | 12 | public class ImprovedPriceCalculatorFactoryTest { 13 | SettingsService settings = mock(SettingsService.class); 14 | private static final BigDecimal MIN_MARGIN = new BigDecimal(20); 15 | private static final BigDecimal MAX_MARGIN = new BigDecimal(30); 16 | private static final BigDecimal PREMIUM_SHARE = new BigDecimal(40); 17 | @Test 18 | public void shouldCreatePriceCalculator() { 19 | //given 20 | given(settings.getMinMargin()).willReturn(MIN_MARGIN); 21 | given(settings.getMaxMargin()).willReturn(MAX_MARGIN); 22 | given(settings.getPremiumShare()).willReturn(PREMIUM_SHARE); 23 | //when 24 | PriceCalculator calculator 25 | = new PriceCalculatorFactory(settings).create(); 26 | //then 27 | assertThat(calculator).isEqualTo( 28 | new PriceCalculator(MIN_MARGIN, MAX_MARGIN, PREMIUM_SHARE)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /smart_values/src/test/java/com/practicalunittesting/PriceCalculatorFactoryTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.testng.annotations.Test; 4 | 5 | import java.math.BigDecimal; 6 | 7 | import static org.assertj.core.api.Assertions.assertThat; 8 | import static org.mockito.BDDMockito.given; 9 | import static org.mockito.Mockito.mock; 10 | 11 | public class PriceCalculatorFactoryTest { 12 | SettingsService settings = mock(SettingsService.class); 13 | @Test 14 | public void shouldCreatePriceCalculator() { 15 | //given 16 | given(settings.getMinMargin()).willReturn(new BigDecimal(20)); 17 | given(settings.getMaxMargin()).willReturn(new BigDecimal(50)); 18 | given(settings.getPremiumShare()).willReturn(new BigDecimal(50)); 19 | //when 20 | PriceCalculator calculator 21 | = new PriceCalculatorFactory(settings).create(); 22 | //then 23 | assertThat(calculator) 24 | .isEqualTo(new PriceCalculator(new BigDecimal(20), 25 | new BigDecimal(50), new BigDecimal(50))); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /test_behaviour/src/main/java/com/practicalunittesting/MailSender.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public interface MailSender { 4 | void sendRegistrationInfo(User savedUser); 5 | } 6 | -------------------------------------------------------------------------------- /test_behaviour/src/main/java/com/practicalunittesting/User.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public interface User { 4 | } 5 | -------------------------------------------------------------------------------- /test_behaviour/src/main/java/com/practicalunittesting/UserData.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public interface UserData { 4 | } 5 | -------------------------------------------------------------------------------- /test_behaviour/src/main/java/com/practicalunittesting/UserRegisterController.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.springframework.validation.BindingResult; 4 | import org.springframework.web.servlet.ModelAndView; 5 | 6 | import javax.servlet.http.HttpServletRequest; 7 | 8 | public class UserRegisterController { 9 | 10 | private UserService userService; 11 | private MailSender mailSender; 12 | 13 | public UserRegisterController(UserService userService, MailSender mailSender) { 14 | this.userService = userService; 15 | this.mailSender = mailSender; 16 | } 17 | 18 | public ModelAndView registerUser(UserData userData, BindingResult result, 19 | HttpServletRequest request) { 20 | if (result.hasErrors()) { 21 | return showRegisterForm(request, false); 22 | } 23 | 24 | User savedUser = userService.saveNewUser(userData); 25 | mailSender.sendRegistrationInfo(savedUser); 26 | return new ModelAndView("redirect:/signin"); 27 | } 28 | 29 | private ModelAndView showRegisterForm(HttpServletRequest request, boolean flag) { 30 | return null; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /test_behaviour/src/main/java/com/practicalunittesting/UserService.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public interface UserService { 4 | User saveNewUser(UserData userData); 5 | } 6 | -------------------------------------------------------------------------------- /test_behaviour/src/test/java/com/practicalunittesting/UserRegisterControllerTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.junit.Test; 4 | import org.springframework.validation.BindingResult; 5 | import org.springframework.web.servlet.ModelAndView; 6 | 7 | import javax.servlet.http.HttpServletRequest; 8 | 9 | import static org.assertj.core.api.Assertions.assertThat; 10 | import static org.mockito.BDDMockito.given; 11 | import static org.mockito.Matchers.eq; 12 | import static org.mockito.Mockito.mock; 13 | import static org.mockito.Mockito.verify; 14 | 15 | public class UserRegisterControllerTest { 16 | 17 | // mocks 18 | UserData userData = mock(UserData.class); 19 | UserService userService = mock(UserService.class); 20 | BindingResult bindingResult = mock(BindingResult.class); 21 | MailSender mailSender = mock(MailSender.class); 22 | User user = mock(User.class); 23 | HttpServletRequest request = mock(HttpServletRequest.class); 24 | 25 | // sut 26 | UserRegisterController userRegisterController = new UserRegisterController(userService, mailSender); 27 | 28 | @Test 29 | public void shouldReturnRedirectViewAndSendEmail() { 30 | //given 31 | given(bindingResult.hasErrors()).willReturn(false); 32 | given(userService.saveNewUser(eq(userData))) 33 | .willReturn(user); 34 | 35 | //when 36 | ModelAndView userRegisterResult = userRegisterController 37 | .registerUser(userData, bindingResult, request); 38 | 39 | //then 40 | assertThat(userRegisterResult.getViewName()) 41 | .isEqualTo("redirect:/signin"); 42 | verify(mailSender).sendRegistrationInfo(user); 43 | } 44 | 45 | @Test 46 | public void shouldRedirectToSigninPageWhenNoErrors() { 47 | //given 48 | given(bindingResult.hasErrors()).willReturn(false); 49 | 50 | //when 51 | ModelAndView userRegisterResult = userRegisterController 52 | .registerUser(userData, bindingResult, request); 53 | 54 | //then 55 | assertThat(userRegisterResult.getViewName()) 56 | .isEqualTo("redirect:/signin"); 57 | } 58 | 59 | @Test 60 | public void shouldNotifyAboutNewUserRegistration() { 61 | //given 62 | given(bindingResult.hasErrors()).willReturn(false); 63 | given(userService.saveNewUser(eq(userData))) 64 | .willReturn(user); 65 | 66 | //when 67 | userRegisterController.registerUser(userData, bindingResult, request); 68 | 69 | //then 70 | verify(mailSender).sendRegistrationInfo(user); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /time_means_trouble/src/main/java/com/practicalunittesting/TimeProvider.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public interface TimeProvider { 4 | String getTime(); 5 | } 6 | -------------------------------------------------------------------------------- /time_means_trouble/src/main/java/com/practicalunittesting/User.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public interface User { 4 | String getFullName(); 5 | } 6 | -------------------------------------------------------------------------------- /time_means_trouble/src/main/java/com/practicalunittesting/Util.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import java.io.UnsupportedEncodingException; 4 | import java.net.URLEncoder; 5 | import java.util.Date; 6 | 7 | public class Util { 8 | 9 | private String baseUrl; 10 | 11 | public String getUrl(User user, String timestamp) throws UnsupportedEncodingException { 12 | String name = user.getFullName(); 13 | 14 | String url = baseUrl 15 | + "name="+ URLEncoder.encode(name, "UTF-8") 16 | + "×tamp="+timestamp; 17 | return url; 18 | } 19 | 20 | public String getUrl(User user) throws UnsupportedEncodingException { 21 | Date date = new Date(); 22 | Long time = (date.getTime() / 1000); //convert ms to seconds 23 | String timestamp = time.toString(); 24 | return getUrl(user, timestamp); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /time_means_trouble/src/main/java/com/practicalunittesting/Util2.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import java.io.UnsupportedEncodingException; 4 | import java.net.URLEncoder; 5 | import java.util.Date; 6 | 7 | public class Util2 { 8 | 9 | private String baseUrl; 10 | private TimeProvider timeProvider; 11 | 12 | public String getUrl(User user, String timestamp) throws UnsupportedEncodingException { 13 | String name = user.getFullName(); 14 | 15 | String url = baseUrl 16 | + "name="+ URLEncoder.encode(name, "UTF-8") 17 | + "×tamp="+timestamp; 18 | return url; 19 | } 20 | 21 | public String getUrl(User user) throws UnsupportedEncodingException { 22 | String timestamp = timeProvider.getTime(); 23 | return getUrl(user, timestamp); 24 | } 25 | 26 | public void set(TimeProvider timeProvider) { 27 | this.timeProvider = timeProvider; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /time_means_trouble/src/test/java/com/practicalunittesting/Util2Test.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | import java.io.UnsupportedEncodingException; 8 | 9 | import static org.assertj.core.api.Assertions.assertThat; 10 | import static org.mockito.BDDMockito.given; 11 | import static org.mockito.Mockito.mock; 12 | import static org.mockito.Mockito.when; 13 | 14 | public class Util2Test { 15 | 16 | User user; 17 | 18 | @Before 19 | public void setUp() { 20 | user = mock(User.class); 21 | given(user.getFullName()).willReturn("username"); 22 | } 23 | 24 | @Test 25 | public void shouldAddTimestampToGeneratedUrl() throws UnsupportedEncodingException { 26 | //given 27 | TimeProvider timeProvider = mock(TimeProvider.class); 28 | Util2 util = new Util2(); 29 | when(timeProvider.getTime()).thenReturn("12345"); 30 | util.set(timeProvider); 31 | 32 | //when 33 | String url = util.getUrl(user); 34 | 35 | //then 36 | assertThat(url).contains("timestamp=12345"); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /time_means_trouble/src/test/java/com/practicalunittesting/UtilTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.junit.Test; 4 | 5 | import java.io.UnsupportedEncodingException; 6 | 7 | import static org.mockito.Matchers.anyString; 8 | import static org.mockito.Matchers.eq; 9 | import static org.mockito.Mockito.mock; 10 | import static org.mockito.Mockito.spy; 11 | import static org.mockito.Mockito.verify; 12 | 13 | public class UtilTest { 14 | 15 | User user = mock(User.class); 16 | 17 | @Test 18 | public void shouldUseTimestampMethod() throws UnsupportedEncodingException { 19 | //given 20 | Util util = new Util(); 21 | Util spyUtil = spy(util); 22 | 23 | //when 24 | spyUtil.getUrl(user); 25 | 26 | //then 27 | verify(spyUtil).getUrl(eq(user), anyString()); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /true_false/src/main/java/com/practicalunittesting/MockServer.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public class MockServer { 4 | public MockServer(Object responseMap, boolean withFile, int port, boolean ssl) { 5 | 6 | } 7 | 8 | public MockServer() { 9 | } 10 | 11 | public void setResponseMap(Object responseMap) { 12 | 13 | } 14 | 15 | public void setResponseType(ResponseType responseType) { 16 | 17 | } 18 | 19 | public void setUrl(String serverUrl) { 20 | 21 | } 22 | 23 | public void setSsl(boolean ssl) { 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /true_false/src/main/java/com/practicalunittesting/ResponseType.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public enum ResponseType { 4 | FILE 5 | } 6 | -------------------------------------------------------------------------------- /true_false/src/test/java/com/practicalunittesting/BuilderTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import java.net.MalformedURLException; 4 | import java.util.Map; 5 | 6 | import static com.practicalunittesting.ResponseType.FILE; 7 | 8 | public class BuilderTest { 9 | 10 | private Map responseMap; 11 | private static final String SERVER_ROOT = "http://whatever.com"; 12 | 13 | public void testMethod() throws MalformedURLException { 14 | MockServer server = new MockServerBuilder() 15 | .withResponse(responseMap) 16 | .withResponseType(FILE) 17 | .withUrl(SERVER_ROOT) 18 | .withoutSsl() 19 | .create(); 20 | } 21 | 22 | private class MockServerBuilder { 23 | private Map responseMap; 24 | private ResponseType responseType; 25 | private String serverUrl; 26 | private boolean ssl; 27 | 28 | public MockServerBuilder withResponse(Map responseMap) { 29 | this.responseMap = responseMap; 30 | return this; 31 | } 32 | 33 | public MockServerBuilder withResponseType(ResponseType responseType) { 34 | this.responseType = responseType; 35 | return this; 36 | } 37 | 38 | public MockServerBuilder withUrl(String serverUrl) { 39 | this.serverUrl = serverUrl; 40 | return this; 41 | } 42 | 43 | public MockServerBuilder withoutSsl() { 44 | this.ssl = false; 45 | return this; 46 | } 47 | 48 | public MockServer create() { 49 | MockServer server = new MockServer(); 50 | server.setResponseMap(responseMap); 51 | server.setResponseType(responseType); 52 | server.setUrl(serverUrl); 53 | server.setSsl(ssl); 54 | return server; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /true_false/src/test/java/com/practicalunittesting/ConstantsTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import java.net.MalformedURLException; 4 | import java.net.URL; 5 | 6 | public class ConstantsTest { 7 | 8 | public static final boolean RESPONSE_IS_A_FILE = true; 9 | public static final boolean NO_SSL = false; 10 | private Object responseMap; 11 | private static final String SERVER_ROOT = "http://whatever.com"; 12 | 13 | public void testMethod() throws MalformedURLException { 14 | MockServer server = new MockServer(responseMap, RESPONSE_IS_A_FILE, 15 | new URL(SERVER_ROOT).getPort(), NO_SSL); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /true_false/src/test/java/com/practicalunittesting/OriginalTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import java.net.MalformedURLException; 4 | import java.net.URL; 5 | 6 | public class OriginalTest { 7 | 8 | private Object responseMap; 9 | private static final String SERVER_ROOT = "http://whatever.com"; 10 | 11 | public void testMethod() throws MalformedURLException { 12 | MockServer server = new MockServer(responseMap, true, 13 | new URL(SERVER_ROOT).getPort(), false); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /true_false/src/test/java/com/practicalunittesting/PrivateMethodTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import java.net.MalformedURLException; 4 | import java.net.URL; 5 | 6 | public class PrivateMethodTest { 7 | 8 | private Object responseMap; 9 | private static final String SERVER_ROOT = "http://whatever.com"; 10 | 11 | public void testMethod() throws MalformedURLException { 12 | MockServer server = noSslFileServer(); 13 | } 14 | 15 | private MockServer noSslFileServer() throws MalformedURLException { 16 | return new MockServer(responseMap, true, 17 | new URL(SERVER_ROOT).getPort(), false); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /valid_and_not_valid/src/main/java/com/practicalunittesting/FieldVerifier.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public class FieldVerifier { 4 | public static boolean isValidQuery(String query) { 5 | return false; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /valid_and_not_valid/src/test/java/com/practicalunittesting/ImprovedQueryTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.testng.annotations.DataProvider; 4 | import org.testng.annotations.Test; 5 | 6 | import static org.testng.Assert.assertFalse; 7 | import static org.testng.Assert.assertTrue; 8 | public class ImprovedQueryTest { 9 | 10 | @DataProvider 11 | public Object[][] validQueries() { 12 | return new Object[][] { {"48"}, {"48123"}, 13 | {"+48"}, {"++48"}, {"+48503"}}; 14 | } 15 | 16 | @Test(dataProvider = "validQueries") 17 | public void shouldRecognizeValidQueries(String validQuery) { 18 | assertTrue(FieldVerifier.isValidQuery(validQuery)); 19 | } 20 | 21 | @DataProvider 22 | public Object[][] invalidQueries() { 23 | return new Object[][] { 24 | {"+4"}, {"++4"}, 25 | {""}, {null}, {" "} }; 26 | } 27 | 28 | @Test(dataProvider = "invalidQueries") 29 | public void shouldRejectInvalidQueries(String invalidQuery) { 30 | assertFalse(FieldVerifier.isValidQuery(invalidQuery)); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /valid_and_not_valid/src/test/java/com/practicalunittesting/QueryTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.testng.annotations.DataProvider; 4 | import org.testng.annotations.Test; 5 | 6 | import static org.testng.AssertJUnit.assertEquals; 7 | 8 | public class QueryTest { 9 | 10 | @DataProvider 11 | public Object[][] data() { 12 | return new Object[][] { {"48", true}, {"+48", true}, 13 | {"++48", true}, {"+48503", true}, {"+4", false}, 14 | {"++4", false}, {"", false}, 15 | {null, false}, {" ", false}, }; 16 | } 17 | 18 | @Test(dataProvider = "data") 19 | public void testQueryVerification(String query, boolean expected) { 20 | assertEquals(expected, FieldVerifier.isValidQuery(query)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /verify_never/src/main/java/com/practicalunittesting/PacketApi.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public enum PacketApi { 4 | ; 5 | public static final String PACKET_PARAMETER = "param"; 6 | public static final String TYPE_PARAMETER = "type"; 7 | } 8 | -------------------------------------------------------------------------------- /verify_never/src/main/java/com/practicalunittesting/PacketDataProcessor.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public class PacketDataProcessor { 4 | public void process(String packet, String type) { 5 | 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /verify_never/src/main/java/com/practicalunittesting/PacketServlet.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import javax.servlet.ServletException; 4 | import javax.servlet.http.HttpServlet; 5 | import javax.servlet.http.HttpServletRequest; 6 | import javax.servlet.http.HttpServletResponse; 7 | import java.io.IOException; 8 | 9 | public class PacketServlet extends HttpServlet { 10 | 11 | @Override 12 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 13 | super.doGet(req, resp); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /verify_never/src/test/java/com/practicalunittesting/PacketServletTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.testng.annotations.BeforeMethod; 4 | import org.testng.annotations.Test; 5 | 6 | import javax.servlet.ServletException; 7 | import javax.servlet.http.HttpServletRequest; 8 | import javax.servlet.http.HttpServletResponse; 9 | import java.io.IOException; 10 | 11 | import static org.mockito.BDDMockito.given; 12 | import static org.mockito.Mockito.*; 13 | 14 | public class PacketServletTest { 15 | 16 | private static final String PACKET = "packet"; 17 | private static final String TYPE = "type"; 18 | HttpServletRequest request; 19 | PacketDataProcessor packetDataProcessor; 20 | HttpServletResponse response; 21 | PacketServlet servlet; 22 | 23 | @BeforeMethod 24 | public void setUp() { 25 | request = mock(HttpServletRequest.class); 26 | response = mock(HttpServletResponse.class); 27 | packetDataProcessor = mock(PacketDataProcessor.class); 28 | } 29 | 30 | @Test 31 | public void shouldProcessPacket() throws IOException, ServletException { 32 | //given 33 | given(request.getParameter(PacketApi.PACKET_PARAMETER)) 34 | .willReturn(PACKET); 35 | given(request.getParameter(PacketApi.TYPE_PARAMETER)) 36 | .willReturn(TYPE); 37 | 38 | //when 39 | servlet.doGet(request, response); 40 | 41 | //then 42 | verify(packetDataProcessor).process(PACKET, TYPE); 43 | } 44 | 45 | @Test 46 | public void shouldNotProcessIfPacketParameterIsMissing() 47 | throws IOException, ServletException { 48 | //given 49 | given(request.getParameter(PacketApi.TYPE_PARAMETER)) 50 | .willReturn(TYPE); 51 | 52 | //when 53 | servlet.doGet(request, response); 54 | 55 | //then 56 | verify(packetDataProcessor, never()).process(PACKET, TYPE); 57 | } 58 | 59 | @Test 60 | public void shouldProcessIfPacketParameterIsMissing() 61 | throws IOException, ServletException { 62 | //given 63 | given(request.getParameter(PacketApi.TYPE_PARAMETER)) 64 | .willReturn(TYPE); 65 | 66 | //when 67 | servlet.doGet(request, response); 68 | 69 | //then 70 | verifyZeroInteractions(packetDataProcessor); 71 | } 72 | 73 | @Test 74 | public void shouldReturnStatus500IfThereWasAnErrorDuringProcessing() 75 | throws IOException, ServletException { 76 | //given 77 | given(request.getParameter(PacketApi.PACKET_PARAMETER)) 78 | .willReturn(PACKET); 79 | given(request.getParameter(PacketApi.TYPE_PARAMETER)) 80 | .willReturn(TYPE); 81 | doThrow(NullPointerException.class) 82 | .when(packetDataProcessor).process(PACKET,TYPE); 83 | 84 | //when 85 | servlet.doGet(request, response); 86 | 87 | //then 88 | verify(response).setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); 89 | } 90 | 91 | @Test 92 | public void shouldReturnStatus500IfThereWasAnErrorDuringProcessing_Improved() 93 | throws IOException, ServletException { 94 | //given 95 | given(request.getParameter(PacketApi.PACKET_PARAMETER)) 96 | .willReturn(PACKET); 97 | given(request.getParameter(PacketApi.TYPE_PARAMETER)) 98 | .willReturn(TYPE); 99 | doThrow(Exception.class) 100 | .when(packetDataProcessor).process(PACKET,TYPE); 101 | 102 | //when 103 | servlet.doGet(request, response); 104 | 105 | //then 106 | verify(response).setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /waste_of_time/src/main/java/com/practicalunittesting/Settings.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import java.math.BigDecimal; 4 | 5 | public interface Settings { 6 | BigDecimal getImportantValue(); 7 | } 8 | -------------------------------------------------------------------------------- /waste_of_time/src/main/java/com/practicalunittesting/SettingsFacade.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import java.math.BigDecimal; 4 | 5 | public class SettingsFacade { 6 | private static final BigDecimal DEFAULT_VALUE = BigDecimal.ZERO; 7 | private final Settings settings; 8 | 9 | public SettingsFacade(Settings settings) { 10 | this.settings = settings; 11 | } 12 | 13 | public BigDecimal getImportantValue() { 14 | return settings.getImportantValue(); 15 | } 16 | 17 | public BigDecimal getImportantValueEvolved() { 18 | return (settings.getImportantValue() != null) 19 | ? settings.getImportantValue() : DEFAULT_VALUE; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /waste_of_time/src/test/java/com/practicalunittesting/SettingsFacadeTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.junit.Test; 4 | 5 | import java.math.BigDecimal; 6 | 7 | import static org.assertj.core.api.Assertions.assertThat; 8 | import static org.mockito.BDDMockito.given; 9 | import static org.mockito.Mockito.mock; 10 | 11 | public class SettingsFacadeTest { 12 | 13 | private static final BigDecimal IMPORTANT_VALUE = new BigDecimal("0.123"); 14 | private Settings settings = mock(Settings.class); 15 | private SettingsFacade settingsFacade = new SettingsFacade(settings); 16 | 17 | @Test 18 | public void shouldReturnImportantValue() { 19 | //given 20 | given(settings.getImportantValue()).willReturn(IMPORTANT_VALUE); 21 | 22 | //when 23 | BigDecimal importantValue = settingsFacade.getImportantValue(); 24 | 25 | //then 26 | assertThat(importantValue).isEqualByComparingTo(IMPORTANT_VALUE); 27 | } 28 | 29 | 30 | @Test 31 | public void shouldReturnImportantValueEvolved() { 32 | //given 33 | given(settings.getImportantValue()).willReturn(IMPORTANT_VALUE); 34 | 35 | //when 36 | BigDecimal importantValue = settingsFacade.getImportantValueEvolved(); 37 | 38 | //then 39 | assertThat(importantValue).isEqualByComparingTo(IMPORTANT_VALUE); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /what_is_asserted/src/main/java/com/practicalunittesting/CompilerSupport.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import java.io.File; 4 | import java.util.List; 5 | 6 | public class CompilerSupport { 7 | public String[] compile(File[] fakes) { 8 | return null; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /what_is_asserted/src/main/java/com/practicalunittesting/CompilerSupportFactory.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | public class CompilerSupportFactory { 4 | 5 | private static CompilerSupport default32BitCompilerSupport; 6 | 7 | public static CompilerSupport getDefault32BitCompilerSupport() { 8 | return default32BitCompilerSupport; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /what_is_asserted/src/test/java/com/practicalunittesting/CompilerTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting; 2 | 3 | import org.testng.annotations.Test; 4 | 5 | import java.io.File; 6 | import java.util.List; 7 | 8 | import static org.hamcrest.CoreMatchers.is; 9 | import static org.hamcrest.MatcherAssert.assertThat; 10 | import static org.hamcrest.Matchers.emptyArray; 11 | 12 | public class CompilerTest { 13 | 14 | @Test 15 | public void testCompile_32Bit_FakeSourceFile() { 16 | CompilerSupport _32BitCompilerSupport 17 | = CompilerSupportFactory.getDefault32BitCompilerSupport(); 18 | testCompile_FakeSourceFile(_32BitCompilerSupport); 19 | } 20 | 21 | private void testCompile_FakeSourceFile( 22 | CompilerSupport compilerSupport) { 23 | String[] compiledFiles 24 | = compilerSupport.compile(new File[] { new File("fake") }); 25 | assertThat(compiledFiles, is(emptyArray())); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /zeros_are_evil/src/main/java/com/practicalunittesting/zero/Client.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting.zero; 2 | 3 | public class Client { 4 | } 5 | -------------------------------------------------------------------------------- /zeros_are_evil/src/main/java/com/practicalunittesting/zero/PaymentAdapter.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting.zero; 2 | 3 | public interface PaymentAdapter { 4 | double getRevenue(Client client, int reportCount); 5 | } 6 | -------------------------------------------------------------------------------- /zeros_are_evil/src/main/java/com/practicalunittesting/zero/PaymentService.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting.zero; 2 | 3 | public class PaymentService { 4 | public static final int REPORT_COUNT = 50; 5 | private PaymentAdapter paymentAdapter; 6 | 7 | public PaymentService(PaymentAdapter paymentAdapter) { 8 | this.paymentAdapter = paymentAdapter; 9 | } 10 | 11 | public double getRevenue(Client client) { 12 | return paymentAdapter.getRevenue(client, REPORT_COUNT); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /zeros_are_evil/src/test/java/com/practicalunittesting/zero/PaymentServiceNonZeroTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting.zero; 2 | 3 | import org.testng.annotations.Test; 4 | 5 | import static org.assertj.core.api.Assertions.assertThat; 6 | import static org.mockito.BDDMockito.given; 7 | import static org.mockito.Mockito.mock; 8 | 9 | public class PaymentServiceNonZeroTest { 10 | 11 | PaymentAdapter paymentAdapter = mock(PaymentAdapter.class); 12 | PaymentService paymentService = new PaymentService(paymentAdapter); 13 | 14 | @Test 15 | public void shouldReturnRevenueForClient() { 16 | //given 17 | final Client client = new Client(); 18 | given(paymentAdapter.getRevenue(client, PaymentService.REPORT_COUNT)).willReturn(1.23); 19 | 20 | //when 21 | double actual = paymentService.getRevenue(client); 22 | 23 | //then 24 | assertThat(actual).isEqualTo(1.23d); 25 | } 26 | } -------------------------------------------------------------------------------- /zeros_are_evil/src/test/java/com/practicalunittesting/zero/PaymentServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.practicalunittesting.zero; 2 | 3 | import org.testng.annotations.Test; 4 | 5 | import static org.assertj.core.api.Assertions.assertThat; 6 | import static org.mockito.BDDMockito.given; 7 | import static org.mockito.Mockito.mock; 8 | 9 | public class PaymentServiceTest { 10 | 11 | PaymentAdapter paymentAdapter = mock(PaymentAdapter.class); 12 | PaymentService paymentService = new PaymentService(paymentAdapter); 13 | 14 | @Test 15 | public void shouldReturnRevenueForClient() { 16 | //given 17 | final Client client = new Client(); 18 | given(paymentAdapter.getRevenue(client, PaymentService.REPORT_COUNT)).willReturn(0d); 19 | 20 | //when 21 | double actual = paymentService.getRevenue(client); 22 | 23 | //then 24 | assertThat(actual).isEqualTo(0d); 25 | } 26 | } --------------------------------------------------------------------------------