Resistance is futile mocks will be assimilated

87
[email protected] - Everis Alex Soto Resistance is Futile, Mocks Will be Assimilated viernes 18 de octubre de 13

description

Conference given at Codemotion Madrid 2013 about writing tests not only using mocks.

Transcript of Resistance is futile mocks will be assimilated

Page 1: Resistance is futile mocks will be assimilated

[email protected] - Everis

Alex Soto

Resistance is Futile, Mocks Will be Assimilated

viernes 18 de octubre de 13

Page 2: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Mocks ?

Mocks are objects pre-programmed with expectations

viernes 18 de octubre de 13

Page 3: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Mocks ?

Mocks are objects pre-programmed with expectations

viernes 18 de octubre de 13

Page 4: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Mocks ?

Fast

viernes 18 de octubre de 13

Page 5: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Mocks ?

Fast

Interface

viernes 18 de octubre de 13

Page 6: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Mocks ?

Fast

Interface

70% Test Code

viernes 18 de octubre de 13

Page 7: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Mocks ?

Fast

Interface

70% Test Code

Hard to Maintain

viernes 18 de octubre de 13

Page 8: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Mocks ?

Fast

Interface

70% Test Code

Hard to Maintain

Container services

viernes 18 de octubre de 13

Page 9: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Mocks ?

Fast

Interface

70% Test Code

Hard to Maintain

Container services

Uncertainty

viernes 18 de octubre de 13

Page 10: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Mocks ?

Fast

Interface

70% Test Code

Hard to Maintain

Container services

Uncertainty

Duplication

viernes 18 de octubre de 13

Page 11: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Mocks ?Kno

w Your

Enem

y?

viernes 18 de octubre de 13

Page 12: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Java EE Scenario

Client Protocol

{text/html}

{app/json}{app/xml}

Server External

{app/json}

viernes 18 de octubre de 13

Page 13: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

High Level Tests

We D

on’t H

ave Tim

e

viernes 18 de octubre de 13

Page 14: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Low Level Tests

State Of The Union

viernes 18 de octubre de 13

Page 15: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Data Layer

Mock DAOs

viernes 18 de octubre de 13

Page 16: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Data Layer

Mock DAOs

Fast

Isolated

viernes 18 de octubre de 13

Page 17: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Data Layer

Mock DAOs

Fast

Isolated

ORM Mapping

ORM Configuration

Queries

viernes 18 de octubre de 13

Page 18: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Data Layer

Fast

viernes 18 de octubre de 13

Page 19: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Data Layer

Fast

viernes 18 de octubre de 13

Page 20: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Data Layer

Fast

viernes 18 de octubre de 13

Page 21: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Data Layer

Isolated

viernes 18 de octubre de 13

Page 22: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Data Layer

Isolated

viernes 18 de octubre de 13

Page 23: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Data Layer

Isolated

Define base data set

CLEAN

INSERT

viernes 18 de octubre de 13

Page 24: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Data Layer

{! "Book":! ! ! [! ! ! ! {"title":"The Hobbit","numberOfPages":293}! ! ! ]}

@Rulepublic MongoDbRule remoteMongoDbRule = newMongoDbRule().defaultManagedMongoDb("db");

@Test@UsingDataSet(locations="data.json",loadStrategy=LoadStrategyEnum.CLEAN_INSERT)@ShouldMatchDataSet(location="expectedData.json")public void book_should_be_inserted_into_repository() {

//test}

viernes 18 de octubre de 13

Page 25: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Data Layer

{! "Book":! ! ! [! ! ! ! {"title":"The Hobbit","numberOfPages":293}! ! ! ]}

@Rulepublic MongoDbRule remoteMongoDbRule = newMongoDbRule().defaultManagedMongoDb("db");

@Test@UsingDataSet(locations="data.json",loadStrategy=LoadStrategyEnum.CLEAN_INSERT)@ShouldMatchDataSet(location="expectedData.json")public void book_should_be_inserted_into_repository() {

//test}

viernes 18 de octubre de 13

Page 26: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Data Layer

{! "Book":! ! ! [! ! ! ! {"title":"The Hobbit","numberOfPages":293}! ! ! ]}

@Rulepublic MongoDbRule remoteMongoDbRule = newMongoDbRule().defaultManagedMongoDb("db");

@Test@UsingDataSet(locations="data.json",loadStrategy=LoadStrategyEnum.CLEAN_INSERT)@ShouldMatchDataSet(location="expectedData.json")public void book_should_be_inserted_into_repository() {

//test}

viernes 18 de octubre de 13

Page 27: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Data Layer

{! "Book":! ! ! [! ! ! ! {"title":"The Hobbit","numberOfPages":293}! ! ! ]}

@Rulepublic MongoDbRule remoteMongoDbRule = newMongoDbRule().defaultManagedMongoDb("db");

@Test@UsingDataSet(locations="data.json",loadStrategy=LoadStrategyEnum.CLEAN_INSERT)@ShouldMatchDataSet(location="expectedData.json")public void book_should_be_inserted_into_repository() {

//test}

viernes 18 de octubre de 13

Page 28: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

E-mail

Mock E-mail access

viernes 18 de octubre de 13

Page 29: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

E-mail

Mock E-mail access

Fast

Offline

viernes 18 de octubre de 13

Page 30: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

E-mail

Mock E-mail access

Fast

Offline

javax.mail

viernes 18 de octubre de 13

Page 31: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

E-mail

SMTPMailService.sendMail(MailMessageBuilder$MailMessage) Transport.send(Message) Transport.send0(Message, Address[]) SMTPTransport.sendMessage(Message, Address[]) MimeMessage.writeTo(OutputStream, String[]) MimeBodyPart.writeTo(MimePart, OutputStream, String[])

viernes 18 de octubre de 13

Page 32: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

E-mail

Embeddable SMTP server

viernes 18 de octubre de 13

Page 33: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

E-mail

private static final int SMTP_PORT = 2500;private static Wiser mailServer = new Wiser();

@BeforeClasspublic static void startWiser() {! mailServer.setPort(SMTP_PORT);! mailServer.start();}

@AfterClasspublic static void stopWiser() {! mailServer.stop();}

@Testpublic void an_email_should_be_sent() throws MessagingException, IOException {

! MailMessage message = mail().from("[email protected]").addTo("[email protected]")! ! ! ! .contentType("text/plain").subject("Welcome")! ! ! ! .body("Welcome to our site, thanks for registering on it.")! ! ! ! .build();

! SMTPMailService smtpMailService = getMailService();! smtpMailService.sendMail(message);

! WiserMessage sentMessage = getSentMessage();! !! String subject = sentMessage.getMimeMessage().getSubject();! assertThat(subject, is("Welcome"));! !}

viernes 18 de octubre de 13

Page 34: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

E-mail

private static final int SMTP_PORT = 2500;private static Wiser mailServer = new Wiser();

@BeforeClasspublic static void startWiser() {! mailServer.setPort(SMTP_PORT);! mailServer.start();}

@AfterClasspublic static void stopWiser() {! mailServer.stop();}

@Testpublic void an_email_should_be_sent() throws MessagingException, IOException {

! MailMessage message = mail().from("[email protected]").addTo("[email protected]")! ! ! ! .contentType("text/plain").subject("Welcome")! ! ! ! .body("Welcome to our site, thanks for registering on it.")! ! ! ! .build();

! SMTPMailService smtpMailService = getMailService();! smtpMailService.sendMail(message);

! WiserMessage sentMessage = getSentMessage();! !! String subject = sentMessage.getMimeMessage().getSubject();! assertThat(subject, is("Welcome"));! !}

viernes 18 de octubre de 13

Page 35: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

E-mail

private static final int SMTP_PORT = 2500;private static Wiser mailServer = new Wiser();

@BeforeClasspublic static void startWiser() {! mailServer.setPort(SMTP_PORT);! mailServer.start();}

@AfterClasspublic static void stopWiser() {! mailServer.stop();}

@Testpublic void an_email_should_be_sent() throws MessagingException, IOException {

! MailMessage message = mail().from("[email protected]").addTo("[email protected]")! ! ! ! .contentType("text/plain").subject("Welcome")! ! ! ! .body("Welcome to our site, thanks for registering on it.")! ! ! ! .build();

! SMTPMailService smtpMailService = getMailService();! smtpMailService.sendMail(message);

! WiserMessage sentMessage = getSentMessage();! !! String subject = sentMessage.getMimeMessage().getSubject();! assertThat(subject, is("Welcome"));! !}

viernes 18 de octubre de 13

Page 36: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

E-mail

private static final int SMTP_PORT = 2500;private static Wiser mailServer = new Wiser();

@BeforeClasspublic static void startWiser() {! mailServer.setPort(SMTP_PORT);! mailServer.start();}

@AfterClasspublic static void stopWiser() {! mailServer.stop();}

@Testpublic void an_email_should_be_sent() throws MessagingException, IOException {

! MailMessage message = mail().from("[email protected]").addTo("[email protected]")! ! ! ! .contentType("text/plain").subject("Welcome")! ! ! ! .body("Welcome to our site, thanks for registering on it.")! ! ! ! .build();

! SMTPMailService smtpMailService = getMailService();! smtpMailService.sendMail(message);

! WiserMessage sentMessage = getSentMessage();! !! String subject = sentMessage.getMimeMessage().getSubject();! assertThat(subject, is("Welcome"));! !}

viernes 18 de octubre de 13

Page 37: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

REST

Mock REST access

viernes 18 de octubre de 13

Page 38: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

REST

Mock REST access

Fast

Offline

viernes 18 de octubre de 13

Page 39: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

REST

Mock REST access

Fast

Offline

Full Call Stack

viernes 18 de octubre de 13

Page 40: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

REST

Stubbing Web Services

viernes 18 de octubre de 13

Page 41: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

REST

private static final String URL = "http://localhost:8089";

@Rulepublic WireMockRule wireMockRule = new WireMockRule(8089);!@Testpublic void issues_from_project_should_be_retrieved() {! !! givenThat(get(urlEqualTo("/repos/lordofthejars/nosqlunit/issues"))! ! .willReturn(aResponse() .withHeader("Content-Type", "application/json") .withBody(GET_RESPONSE_JSON))! );! !! GithubClient githubClient = new GithubClient(URL);! !! String issues = githubClient.invokeGetMethod("/repos/lordofthejars/nosqlunit/issues");

! //could be an object assertThat(issues, is(GET_RESPONSE_JSON));! !}

viernes 18 de octubre de 13

Page 42: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

REST

private static final String URL = "http://localhost:8089";

@Rulepublic WireMockRule wireMockRule = new WireMockRule(8089);!@Testpublic void issues_from_project_should_be_retrieved() {! !! givenThat(get(urlEqualTo("/repos/lordofthejars/nosqlunit/issues"))! ! .willReturn(aResponse() .withHeader("Content-Type", "application/json") .withBody(GET_RESPONSE_JSON))! );! !! GithubClient githubClient = new GithubClient(URL);! !! String issues = githubClient.invokeGetMethod("/repos/lordofthejars/nosqlunit/issues");

! //could be an object assertThat(issues, is(GET_RESPONSE_JSON));! !}

viernes 18 de octubre de 13

Page 43: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

REST

private static final String URL = "http://localhost:8089";

@Rulepublic WireMockRule wireMockRule = new WireMockRule(8089);!@Testpublic void issues_from_project_should_be_retrieved() {! !! givenThat(get(urlEqualTo("/repos/lordofthejars/nosqlunit/issues"))! ! .willReturn(aResponse() .withHeader("Content-Type", "application/json") .withBody(GET_RESPONSE_JSON))! );! !! GithubClient githubClient = new GithubClient(URL);! !! String issues = githubClient.invokeGetMethod("/repos/lordofthejars/nosqlunit/issues");

! //could be an object assertThat(issues, is(GET_RESPONSE_JSON));! !}

viernes 18 de octubre de 13

Page 44: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

REST

private static final String URL = "http://localhost:8089";

@Rulepublic WireMockRule wireMockRule = new WireMockRule(8089);!@Testpublic void issues_from_project_should_be_retrieved() {! !! givenThat(get(urlEqualTo("/repos/lordofthejars/nosqlunit/issues"))! ! .willReturn(aResponse() .withHeader("Content-Type", "application/json") .withBody(GET_RESPONSE_JSON))! );! !! GithubClient githubClient = new GithubClient(URL);! !! String issues = githubClient.invokeGetMethod("/repos/lordofthejars/nosqlunit/issues");

! //could be an object assertThat(issues, is(GET_RESPONSE_JSON));! !}

viernes 18 de octubre de 13

Page 45: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Container

Code Runs in Container

viernes 18 de octubre de 13

Page 46: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Container

Code Runs in Container

CDI (Qualifiers, Produces, Alternatives, Decorators)

JPA (EntityManager, Transactions, Mapping)

Security

JSF (Conversation Scope, Binding, Validation)

JAX-RS, JAX-WS, ...

viernes 18 de octubre de 13

Page 47: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Container

public class PaymentGateway {

@Inject @CreditCard PaymentProcessor paymentProcessor//...public void setPaymentProcessor(PaymentProcessor paymentProcessor) {...}

}

Are you sure it works?

viernes 18 de octubre de 13

Page 48: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Container

Brings tests to runtime

viernes 18 de octubre de 13

Page 49: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Container

Brings tests to runtime

Manage Lifecycle of Container

viernes 18 de octubre de 13

Page 50: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Container

Brings tests to runtime

Manage Lifecycle of Container

Create/Deploy MicroDeployments

viernes 18 de octubre de 13

Page 51: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Container

Brings tests to runtime

Manage Lifecycle of Container

Create/Deploy MicroDeployments

Enriching Test Classes

viernes 18 de octubre de 13

Page 52: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Container

Brings tests to runtime

Manage Lifecycle of Container

Create/Deploy MicroDeployments

Enriching Test Classes

Run Tests Inside/Against Container

viernes 18 de octubre de 13

Page 53: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Container

Brings tests to runtime

Manage Lifecycle of Container

Create/Deploy MicroDeployments

Enriching Test Classes

Run Tests Inside/Against Container

IDE Friendly

viernes 18 de octubre de 13

Page 54: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Container

viernes 18 de octubre de 13

Page 55: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Container

viernes 18 de octubre de 13

Page 56: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Container

viernes 18 de octubre de 13

Page 57: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Alex Soto

viernes 18 de octubre de 13

Page 58: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Container

viernes 18 de octubre de 13

Page 59: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Container

viernes 18 de octubre de 13

Page 60: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobSpeaker’s name

Slide’s title

Let’s see in Action

viernes 18 de octubre de 13

Page 61: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

UI

UI code

DOM Manipulation

Ajax

Widgets

viernes 18 de octubre de 13

Page 62: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

UI

Drives the browser

Access web elements

viernes 18 de octubre de 13

Page 63: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

UI

driver.get(contextPath.toString()+"login.xhtml");! !WebElement username = driver.findElement(By.id("username"));WebElement password = driver.findElement(By.id("password"));WebElement submit = driver.findElement(By.id("submit"));! !username.sendKeys("aa");password.sendKeys("bb");! !submit.click();! !WebElement welcomeMessage = driver.findElement(By.id("welcomeMessage"));

assertThat(welcomeMessage.getText(), is("Welcome"));

viernes 18 de octubre de 13

Page 64: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

UI

driver.get(contextPath.toString()+"login.xhtml");! !WebElement username = driver.findElement(By.id("username"));WebElement password = driver.findElement(By.id("password"));WebElement submit = driver.findElement(By.id("submit"));! !username.sendKeys("aa");password.sendKeys("bb");! !submit.click();! !WebElement welcomeMessage = driver.findElement(By.id("welcomeMessage"));

assertThat(welcomeMessage.getText(), is("Welcome"));

viernes 18 de octubre de 13

Page 65: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

UI

Arquillian Drone/Graphene

Sexy WebDriver API

Ajax-enabled

PageObjects

JQuery selectors

Call Javascript as Java

viernes 18 de octubre de 13

Page 66: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

UI

Let’s see in Action

viernes 18 de octubre de 13

Page 67: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Faults

Mock Fauls

viernes 18 de octubre de 13

Page 68: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Faults

Mock Fauls

Race Conditions

Uncommon Exceptions

viernes 18 de octubre de 13

Page 69: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Faults

Mock Fauls

Race Conditions

Uncommon Exceptions

Test Until Last Line

viernes 18 de octubre de 13

Page 70: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Faults

Fault Injection

Modify Bytecode

viernes 18 de octubre de 13

Page 71: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Faults

@Test(expected = ”IOException.class”)@BMRule(! ! name="throw IOException writting content",! ! targetClass = "com.lordofthejars.byteman.util.FileUtils",! ! targetMethod = "createFileWithContent",! ! targetLocation = "CALL BufferedWriter.write(String)",! ! action = "throw new java.io.IOException()"! ! )public void an_exception_should_be_thrown() throws IOException {! !! BackupManager backupManager = createBackupManager();! !! backupManager.backupData("Hello World");! !}

public void createFileWithContent(File filename, String content) throws IOException {

! ! ! BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);! ! ! bufferedWriter.write(content);}

viernes 18 de octubre de 13

Page 72: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Faults

@Test(expected = ”IOException.class”)@BMRule(! ! name="throw IOException writting content",! ! targetClass = "com.lordofthejars.byteman.util.FileUtils",! ! targetMethod = "createFileWithContent",! ! targetLocation = "CALL BufferedWriter.write(String)",! ! action = "throw new java.io.IOException()"! ! )public void an_exception_should_be_thrown() throws IOException {! !! BackupManager backupManager = createBackupManager();! !! backupManager.backupData("Hello World");! !}

public void createFileWithContent(File filename, String content) throws IOException {

! ! ! BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);! ! ! bufferedWriter.write(content);}

viernes 18 de octubre de 13

Page 73: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Faults

@Test(expected = ”IOException.class”)@BMRule(! ! name="throw IOException writting content",! ! targetClass = "com.lordofthejars.byteman.util.FileUtils",! ! targetMethod = "createFileWithContent",! ! targetLocation = "CALL BufferedWriter.write(String)",! ! action = "throw new java.io.IOException()"! ! )public void an_exception_should_be_thrown() throws IOException {! !! BackupManager backupManager = createBackupManager();! !! backupManager.backupData("Hello World");! !}

public void createFileWithContent(File filename, String content) throws IOException {

! ! ! BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);! ! ! bufferedWriter.write(content);}

viernes 18 de octubre de 13

Page 74: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Continuous Integration/Delivery

Continuous Integration / Delivery

viernes 18 de octubre de 13

Page 75: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Continuous Integration/Delivery

Continuous Integration / Delivery

Commit Stage

viernes 18 de octubre de 13

Page 76: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Continuous Integration/Delivery

Continuous Integration / Delivery

Commit Stage

Mock Expensive Operations

viernes 18 de octubre de 13

Page 77: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Continuous Integration/Delivery

Continuous Integration / Delivery

Commit Stage

Mock Expensive Operations

Monitor Tests

viernes 18 de octubre de 13

Page 78: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Continuous Integration/Delivery

Continuous Integration / Delivery

Commit Stage

Mock Expensive Operations

Monitor Tests

Bye Bye Uncertainty

viernes 18 de octubre de 13

Page 79: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Recap

viernes 18 de octubre de 13

Page 80: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Recap

Mock is an option, not a rule

viernes 18 de octubre de 13

Page 81: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Recap

Mock is an option, not a rule

Tests are first citizens

viernes 18 de octubre de 13

Page 82: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Recap

Mock is an option, not a rule

Tests are first citizens

Don’t let mocks ruin your quality

viernes 18 de octubre de 13

Page 83: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Recap

Mock is an option, not a rule

Tests are first citizens

Don’t let mocks ruin your quality

Remember TDD

viernes 18 de octubre de 13

Page 84: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Recap

Mock is an option, not a rule

Tests are first citizens

Don’t let mocks ruin your quality

Remember TDD

Long Live and Prosper to Tests

viernes 18 de octubre de 13

Page 85: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Engage

viernes 18 de octubre de 13

Page 86: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Contents

https://github.com/lordofthejars/foobank/

viernes 18 de octubre de 13

Page 87: Resistance is futile mocks will be assimilated

www.lordofthejars - @alexsotobAlex Soto

Questions?

Let the end of the world come tumbling down, I'll be the last man standing on the ground - Alive - MeatLoaf

Alex Sotowww.lordofthejars.com@alexsotob

viernes 18 de octubre de 13