SlideShare une entreprise Scribd logo
1  sur  44
You don’t need unit tests!
Sebastian Malaca
Who am I?
Fanatic of the OOP and the Code’s Quality
Blogger
Speaker
Trainer and consultant
Software Developer at Luxoft
@SebastianMalaca
letstalkaboutjava.blogspot.com
Let me tell you a story…
Unit tests - what we will gain?
Documentation
Easy to Refactor
Easy to Modify
Testable Code = good Design
Safety
Not so good….
Documentation? Or implementation?
void apply(ClassCode code) {
if (code.isComplex() || code.isUnreadable()) {
refactor(code);
}
}
@Test
public void shouldRefactorCodeWhenIsUnreadable() { ... }
@Test
public void shouldRefactorCodeWhenIsComplex() { ... }
@Test
public void shouldNotRefactorCodeWhenIsNotComplexNorUnreadable() { ... }
Documentation? Or implementation?
void apply(ClassCode code) {
if (code.isComplexOrUnreadable()) {
refactor(code);
}
}
@Test
public void shouldRefactorCodeWhenIsComplexOrUnreadable() { ... }
@Test
public void shouldNotRefactorCodeWhenIsNotComplexNorUnreadable() { ... }
Documentation? Or implementation?
void apply(ClassCode code) {
if (code.isComplexOrUnreadable() && code.isEditable()) {
refactor(code);
}
}
@Test
public void shouldRefactorCodeWhenIsComplexOrUnreadableAndEditable()
{ ... }
@Test
public void shouldNotRefactorCodeWhenIsComplexOrUnreadableAndNotEditable()
{ ... }
@Test
public void shouldNotRefactorCodeWhenIsNotComplexNorUnreadableAndEditable ()
{ ... }
@Test
public void shouldNotRefactorCodeWhenIsNotComplexNorUnreadableAndNotEditable ()
{ ... }
What you have to understand to understand tests?
void apply(ClassCode code) {
if (code.isComplex() || code.isUnreadable()) {
refactor(code);
}
}
complex unreadable
yes yes
yes no
no yes
no no
What you have to understand to understand tests?
@Test
public void
shouldRefactorCodeWhenIsComplexAndUnreadable() {
ClassCode code = mock(ClassCode.class);
given(code.isComplex()).willReturn(true);
given(code.isUnreadable()).willReturn(true);
processor.apply(code);
// assertion
}
void apply(ClassCode code) {
if (code.isComplex() || code.isUnreadable()) {
refactor(code);
}
}
complex unreadable
yes yes
yes no
no yes
no no
What you have to understand to understand tests?
@Test
public void shouldRefactorCodeWhenIsComplex() {
ClassCode code = mock(ClassCode.class);
given(code.isComplex()).willReturn(true);
processor.apply(code);
// assertion
}
void apply(ClassCode code) {
if (code.isComplex() || code.isUnreadable()) {
refactor(code);
}
}
complex unreadable
yes yes
yes no
no yes
no no
What you have to understand to understand tests?
@Test
public void shouldRefactorCodeWhenIsUnreadable() {
ClassCode code = mock(ClassCode.class);
given(code.isUnreadable()).willReturn(true);
processor.apply(code);
// assertion
}
void apply(ClassCode code) {
if (code.isComplex() || code.isUnreadable()) {
refactor(code);
}
}
complex unreadable
yes yes
yes no
no yes
no no
What you have to understand to understand tests?
@Test
public void
shouldNotRefactorCodeWhenIsNotComplexNorUnreadable() {
ClassCode code = mock(ClassCode.class);
processor.apply(code);
// assertion
}
void apply(ClassCode code) {
if (code.isComplex() || code.isUnreadable()) {
refactor(code);
}
}
complex unreadable
yes yes
yes no
no yes
no no
Too much is too much…
void refactor(ClassCode code, Developer developer) {
if (gitRepository.testsExistsFor(code.getClassName())) {
Roles roles = developer.getRoles();
if (code.mayBeModifiedBy(roles)) {
GitLogin login = developer.getGitLogin();
startRefactoringOf(code, login);
}
}
}
void refactor(ClassCode code, Developer developer) {
if (gitRepository.testsExistsFor(code.getClassName())) {
Roles roles = developer.getRoles();
if (code.mayBeModifiedBy(roles)) {
GitLogin login = developer.getGitLogin();
startRefactoringOf(code, login);
}
}
}
Too much is too much…
@Test
public void shouldNotRefactorWhenTestsDoesNotExist()
{ ... }
@Test
public void shouldNotRefactorWhenTestsExistsAndDeveloperCannotModifyCode()
{ ... }
@Test
public void shouldRefactorWhenTestsExistsAndDeveloperCanModifyCode()
{ ... }
void refactor(ClassCode code, Developer developer) {
if (gitRepository.testsExistsFor(code.getClassName())) {
Roles roles = developer.getRoles();
if (code.mayBeModifiedBy(roles)) {
GitLogin login = developer.getGitLogin();
startRefactoringOf(code, login);
}
}
}
Too much is too much…
private static final GitLogin SOME_GIT_LOGIN = mock(GitLogin.class);
private static final Roles SOME_ROLES = mock(Roles.class);
private static final String SOME_CLASS_NAME = "SomeClass";
@Mock private ClassCode code;
@Mock private Developer developer;
@Before
public void init() {
given(code.getClassName()).willReturn(SOME_CLASS_NAME);
given(developer.getRoles()).willReturn(SOME_ROLES);
given(developer.getGitLogin()).willReturn(SOME_GIT_LOGIN);
}
Do you really feel safe?
public class ProcessingHandler {
private final List<Processor> processors;
public ProcessingHandler(List<Processor> processors) {
this.processors = processors;
}
public Output process(Input input) {
for (Processor processor : processors) {
if (processor.isApplicableFor(input)) {
return processor.process(input);
}
}
return DEFAULT_OUTPUT;
}
}
Do you really feel safe?
public Output process(Input input) {
for (Processor processor : processors) {
if (processor.isApplicableFor(input)) {
return processor.process(input);
}
}
return DEFAULT_OUTPUT;
}
@Test
public void shouldReturnDefaultOutputWhenApplicableProcessorNotFound()
{ ... }
@Test
public void shouldReturnOutputCreatedByApplicableProcessor()
{ ... }
Do you really feel safe?
public class ProcessingHandler {
private final List<Processor> processors;
public ProcessingHandler(List<Processor> processors) {
this.processors = processors;
}
// some code
}
<bean id="processingHandler"
class="com.smalaca.processor.ProcessingHandler">
<constructor-arg name="processors">
<bean class="com.smalaca.processor.ConcreteProcessor1"/>
<bean class="com.smalaca.processor.ConcreteProcessor2"/>
<bean class="com.smalaca.processor.ConcreteProcessor3"/>
</constructor-arg>
</bean>
Assumptions may change…
public class ConcreteProcessor1 extends Processor {
public Output process(Input input) {
return anOututFor(input);
}
// some code
}
Assumptions may change…
public class ConcreteProcessor1 extends Processor {
public Output process(Input input) {
if (isEverythingOk(input)) {
return anOututFor(input);
}
return null;
}
// some code
}
public class ConcreteProcessor1 extends Processor {
public Output process(Input input) {
return anOututFor(input);
}
// some code
}
Assumptions may change…
public Output process(Input input) {
for (Processor processor : processors) {
if (processor.isApplicableFor(input)) {
return processor.process(input);
}
}
return DEFAULT_OUTPUT;
}
public class ConcreteProcessor1 extends Processor {
public Output process(Input input) {
if (isEverythingOk(input)) {
return anOututFor(input);
}
return null;
}
// some code
}
Assumptions may change…
public Output process(Input input) {
for (Processor processor : processors) {
if (processor.isApplicableFor(input)) {
return processor.process(input);
}
}
return DEFAULT_OUTPUT;
}
public class ConcreteProcessor1 extends Processor {
public Output process(Input input) {
if (isEverythingOk(input)) {
return anOututFor(input);
}
return null;
}
// some code
}
Assumptions may change…
public Output process(Input input) {
if (processor.isApplicableFor(input)) {
return processor.process(input);
}
return DEFAULT_OUTPUT;
}
public class ConcreteProcessor1 extends Processor {
public Output process(Input input) {
if (isEverythingOk(input)) {
return anOututFor(input);
}
return null;
}
// some code
}
Assumptions may change…
@Test
public void shouldReturnDefaultOutputWhenApplicableProcessorNotFound() {
given(processor.isApplicableFor(SOME_INPUT)).willReturn(false);
// some code
}
@Test
public void shouldReturnOutputCreatedByApplicableProcessor() {
given(processor.isApplicableFor(SOME_INPUT)).willReturn(true);
given(processor.process(SOME_INPUT)).willReturn(SOME_OUTPUT);
// some code
}
public Output process(Input input) {
if (processor.isApplicableFor(input)) {
return processor.process(input);
}
return DEFAULT_OUTPUT;
}
You really can feel safe…
Implementation or funcationality?
Why, not How
Modifiers and accesors?
TDD – be lazy in a good way
void apply(ClassCode code) {
if (code.isComplex() || code.isUnreadable()) {
refactor(code);
}
}
TDD – be lazy in a good way
@Test
public void shouldRefactorCodeWhenCodeShouldBeImproved() {
given(code.shouldBeImproved()).willReturn(true);
// test
}
@Test
public void shouldNotRefactorCodeWhenCodeDoesNotHaveToBeImproved() {
given(code.shouldBeImproved()).willReturn(false);
// test
}
void apply(ClassCode code) {
if (code.isComplex() || code.isUnreadable()) {
refactor(code);
}
}
Component Tests!
Normal flow
Most critical scenarios
Public API and package private
Refactoring/Redesign
Boundaries
Boundary Object
Integration/Component Tests
What to mock and what not to?
Don’t Mock everything!
Less assumptions
Creation is light
Input
Change = fast feedback
You are the owner
Do you really need unit tests?
JDD 2016 - Sebastian Malaca - You Dont Need Unit Tests

Contenu connexe

Tendances

Presentation_C++UnitTest
Presentation_C++UnitTestPresentation_C++UnitTest
Presentation_C++UnitTestRaihan Masud
 
MUTANTS KILLER (Revised) - PIT: state of the art of mutation testing system
MUTANTS KILLER (Revised) - PIT: state of the art of mutation testing system MUTANTS KILLER (Revised) - PIT: state of the art of mutation testing system
MUTANTS KILLER (Revised) - PIT: state of the art of mutation testing system Tarin Gamberini
 
TDD and the Legacy Code Black Hole
TDD and the Legacy Code Black HoleTDD and the Legacy Code Black Hole
TDD and the Legacy Code Black HoleNoam Kfir
 
Test driven development
Test driven developmentTest driven development
Test driven developmentJohn Walsh
 
Working With Legacy Code
Working With Legacy CodeWorking With Legacy Code
Working With Legacy CodeAndrea Polci
 
Unit testing legacy code
Unit testing legacy codeUnit testing legacy code
Unit testing legacy codeLars Thorup
 
Mutation Testing
Mutation TestingMutation Testing
Mutation TestingESUG
 
Mockito vs JMockit, battle of the mocking frameworks
Mockito vs JMockit, battle of the mocking frameworksMockito vs JMockit, battle of the mocking frameworks
Mockito vs JMockit, battle of the mocking frameworksEndranNL
 
RelProxy, Easy Class Reload and Scripting with Java
RelProxy, Easy Class Reload and Scripting with JavaRelProxy, Easy Class Reload and Scripting with Java
RelProxy, Easy Class Reload and Scripting with JavaJose María Arranz
 
Introduction To J unit
Introduction To J unitIntroduction To J unit
Introduction To J unitOlga Extone
 
Working Effectively with Legacy Code
Working Effectively with Legacy CodeWorking Effectively with Legacy Code
Working Effectively with Legacy Codeslicklash
 
Test driven development and unit testing with examples in C++
Test driven development and unit testing with examples in C++Test driven development and unit testing with examples in C++
Test driven development and unit testing with examples in C++Hong Le Van
 
Applying TDD to Legacy Code
Applying TDD to Legacy CodeApplying TDD to Legacy Code
Applying TDD to Legacy CodeAlexander Goida
 
The why and how of moving to php 7.x
The why and how of moving to php 7.xThe why and how of moving to php 7.x
The why and how of moving to php 7.xWim Godden
 
The why and how of moving to php 7.x
The why and how of moving to php 7.xThe why and how of moving to php 7.x
The why and how of moving to php 7.xWim Godden
 

Tendances (20)

Presentation_C++UnitTest
Presentation_C++UnitTestPresentation_C++UnitTest
Presentation_C++UnitTest
 
MUTANTS KILLER (Revised) - PIT: state of the art of mutation testing system
MUTANTS KILLER (Revised) - PIT: state of the art of mutation testing system MUTANTS KILLER (Revised) - PIT: state of the art of mutation testing system
MUTANTS KILLER (Revised) - PIT: state of the art of mutation testing system
 
TDD and the Legacy Code Black Hole
TDD and the Legacy Code Black HoleTDD and the Legacy Code Black Hole
TDD and the Legacy Code Black Hole
 
Php unit (eng)
Php unit (eng)Php unit (eng)
Php unit (eng)
 
Python unit testing
Python unit testingPython unit testing
Python unit testing
 
Test driven development
Test driven developmentTest driven development
Test driven development
 
Working With Legacy Code
Working With Legacy CodeWorking With Legacy Code
Working With Legacy Code
 
Unit testing (eng)
Unit testing (eng)Unit testing (eng)
Unit testing (eng)
 
Unit testing legacy code
Unit testing legacy codeUnit testing legacy code
Unit testing legacy code
 
Mutation Testing
Mutation TestingMutation Testing
Mutation Testing
 
Mockito vs JMockit, battle of the mocking frameworks
Mockito vs JMockit, battle of the mocking frameworksMockito vs JMockit, battle of the mocking frameworks
Mockito vs JMockit, battle of the mocking frameworks
 
J Unit
J UnitJ Unit
J Unit
 
RelProxy, Easy Class Reload and Scripting with Java
RelProxy, Easy Class Reload and Scripting with JavaRelProxy, Easy Class Reload and Scripting with Java
RelProxy, Easy Class Reload and Scripting with Java
 
Introduction To J unit
Introduction To J unitIntroduction To J unit
Introduction To J unit
 
Working Effectively with Legacy Code
Working Effectively with Legacy CodeWorking Effectively with Legacy Code
Working Effectively with Legacy Code
 
Test driven development and unit testing with examples in C++
Test driven development and unit testing with examples in C++Test driven development and unit testing with examples in C++
Test driven development and unit testing with examples in C++
 
Applying TDD to Legacy Code
Applying TDD to Legacy CodeApplying TDD to Legacy Code
Applying TDD to Legacy Code
 
The why and how of moving to php 7.x
The why and how of moving to php 7.xThe why and how of moving to php 7.x
The why and how of moving to php 7.x
 
The why and how of moving to php 7.x
The why and how of moving to php 7.xThe why and how of moving to php 7.x
The why and how of moving to php 7.x
 
Doing the Impossible
Doing the ImpossibleDoing the Impossible
Doing the Impossible
 

Similaire à JDD 2016 - Sebastian Malaca - You Dont Need Unit Tests

Working effectively with legacy code
Working effectively with legacy codeWorking effectively with legacy code
Working effectively with legacy codeShriKant Vashishtha
 
TDD And Refactoring
TDD And RefactoringTDD And Refactoring
TDD And RefactoringNaresh Jain
 
The craft of meta programming on JVM
The craft of meta programming on JVMThe craft of meta programming on JVM
The craft of meta programming on JVMIgor Khotin
 
SystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features SummarySystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features SummaryAmal Khailtash
 
Navigating the xDD Alphabet Soup
Navigating the xDD Alphabet SoupNavigating the xDD Alphabet Soup
Navigating the xDD Alphabet SoupDror Helper
 
Iterative architecture
Iterative architectureIterative architecture
Iterative architectureJoshuaRizzo4
 
Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev
 Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev
Making Your Own Static Analyzer Using Freud DSL. Marat VyshegorodtsevYandex
 
Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoinknight1128
 
Paradigmas de linguagens de programacao - aula#9
Paradigmas de linguagens de programacao - aula#9Paradigmas de linguagens de programacao - aula#9
Paradigmas de linguagens de programacao - aula#9Ismar Silveira
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to javaciklum_ods
 
Do I need tests when I have the compiler - Andrzej Jóźwiak - TomTom Dev Day 2020
Do I need tests when I have the compiler - Andrzej Jóźwiak - TomTom Dev Day 2020Do I need tests when I have the compiler - Andrzej Jóźwiak - TomTom Dev Day 2020
Do I need tests when I have the compiler - Andrzej Jóźwiak - TomTom Dev Day 2020Andrzej Jóźwiak
 
Back-2-Basics: .NET Coding Standards For The Real World (2011)
Back-2-Basics: .NET Coding Standards For The Real World (2011)Back-2-Basics: .NET Coding Standards For The Real World (2011)
Back-2-Basics: .NET Coding Standards For The Real World (2011)David McCarter
 
Refactoring - improving the smell of your code
Refactoring - improving the smell of your codeRefactoring - improving the smell of your code
Refactoring - improving the smell of your codevmandrychenko
 
10 Typical Problems in Enterprise Java Applications
10 Typical Problems in Enterprise Java Applications10 Typical Problems in Enterprise Java Applications
10 Typical Problems in Enterprise Java ApplicationsEberhard Wolff
 
Daggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processorDaggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processorBartosz Kosarzycki
 
Boosting Your Testing Productivity with Groovy
Boosting Your Testing Productivity with GroovyBoosting Your Testing Productivity with Groovy
Boosting Your Testing Productivity with GroovyJames Williams
 

Similaire à JDD 2016 - Sebastian Malaca - You Dont Need Unit Tests (20)

Working effectively with legacy code
Working effectively with legacy codeWorking effectively with legacy code
Working effectively with legacy code
 
TDD And Refactoring
TDD And RefactoringTDD And Refactoring
TDD And Refactoring
 
The craft of meta programming on JVM
The craft of meta programming on JVMThe craft of meta programming on JVM
The craft of meta programming on JVM
 
SystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features SummarySystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features Summary
 
Navigating the xDD Alphabet Soup
Navigating the xDD Alphabet SoupNavigating the xDD Alphabet Soup
Navigating the xDD Alphabet Soup
 
Iterative architecture
Iterative architectureIterative architecture
Iterative architecture
 
Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev
 Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev
Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev
 
Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoin
 
Paradigmas de linguagens de programacao - aula#9
Paradigmas de linguagens de programacao - aula#9Paradigmas de linguagens de programacao - aula#9
Paradigmas de linguagens de programacao - aula#9
 
E:\Plp 2009 2\Plp 9
E:\Plp 2009 2\Plp 9E:\Plp 2009 2\Plp 9
E:\Plp 2009 2\Plp 9
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to java
 
Core java
Core javaCore java
Core java
 
JUnit 5
JUnit 5JUnit 5
JUnit 5
 
Do I need tests when I have the compiler - Andrzej Jóźwiak - TomTom Dev Day 2020
Do I need tests when I have the compiler - Andrzej Jóźwiak - TomTom Dev Day 2020Do I need tests when I have the compiler - Andrzej Jóźwiak - TomTom Dev Day 2020
Do I need tests when I have the compiler - Andrzej Jóźwiak - TomTom Dev Day 2020
 
Back-2-Basics: .NET Coding Standards For The Real World (2011)
Back-2-Basics: .NET Coding Standards For The Real World (2011)Back-2-Basics: .NET Coding Standards For The Real World (2011)
Back-2-Basics: .NET Coding Standards For The Real World (2011)
 
Refactoring - improving the smell of your code
Refactoring - improving the smell of your codeRefactoring - improving the smell of your code
Refactoring - improving the smell of your code
 
10 Typical Problems in Enterprise Java Applications
10 Typical Problems in Enterprise Java Applications10 Typical Problems in Enterprise Java Applications
10 Typical Problems in Enterprise Java Applications
 
What's New in Groovy 1.6?
What's New in Groovy 1.6?What's New in Groovy 1.6?
What's New in Groovy 1.6?
 
Daggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processorDaggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processor
 
Boosting Your Testing Productivity with Groovy
Boosting Your Testing Productivity with GroovyBoosting Your Testing Productivity with Groovy
Boosting Your Testing Productivity with Groovy
 

Dernier

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesBoston Institute of Analytics
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024SynarionITSolutions
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 

Dernier (20)

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 

JDD 2016 - Sebastian Malaca - You Dont Need Unit Tests

  • 1. You don’t need unit tests! Sebastian Malaca
  • 2. Who am I? Fanatic of the OOP and the Code’s Quality Blogger Speaker Trainer and consultant Software Developer at Luxoft @SebastianMalaca letstalkaboutjava.blogspot.com
  • 3. Let me tell you a story…
  • 4. Unit tests - what we will gain? Documentation Easy to Refactor Easy to Modify Testable Code = good Design Safety
  • 5.
  • 6.
  • 8. Documentation? Or implementation? void apply(ClassCode code) { if (code.isComplex() || code.isUnreadable()) { refactor(code); } } @Test public void shouldRefactorCodeWhenIsUnreadable() { ... } @Test public void shouldRefactorCodeWhenIsComplex() { ... } @Test public void shouldNotRefactorCodeWhenIsNotComplexNorUnreadable() { ... }
  • 9. Documentation? Or implementation? void apply(ClassCode code) { if (code.isComplexOrUnreadable()) { refactor(code); } } @Test public void shouldRefactorCodeWhenIsComplexOrUnreadable() { ... } @Test public void shouldNotRefactorCodeWhenIsNotComplexNorUnreadable() { ... }
  • 10. Documentation? Or implementation? void apply(ClassCode code) { if (code.isComplexOrUnreadable() && code.isEditable()) { refactor(code); } } @Test public void shouldRefactorCodeWhenIsComplexOrUnreadableAndEditable() { ... } @Test public void shouldNotRefactorCodeWhenIsComplexOrUnreadableAndNotEditable() { ... } @Test public void shouldNotRefactorCodeWhenIsNotComplexNorUnreadableAndEditable () { ... } @Test public void shouldNotRefactorCodeWhenIsNotComplexNorUnreadableAndNotEditable () { ... }
  • 11.
  • 12. What you have to understand to understand tests? void apply(ClassCode code) { if (code.isComplex() || code.isUnreadable()) { refactor(code); } } complex unreadable yes yes yes no no yes no no
  • 13. What you have to understand to understand tests? @Test public void shouldRefactorCodeWhenIsComplexAndUnreadable() { ClassCode code = mock(ClassCode.class); given(code.isComplex()).willReturn(true); given(code.isUnreadable()).willReturn(true); processor.apply(code); // assertion } void apply(ClassCode code) { if (code.isComplex() || code.isUnreadable()) { refactor(code); } } complex unreadable yes yes yes no no yes no no
  • 14. What you have to understand to understand tests? @Test public void shouldRefactorCodeWhenIsComplex() { ClassCode code = mock(ClassCode.class); given(code.isComplex()).willReturn(true); processor.apply(code); // assertion } void apply(ClassCode code) { if (code.isComplex() || code.isUnreadable()) { refactor(code); } } complex unreadable yes yes yes no no yes no no
  • 15. What you have to understand to understand tests? @Test public void shouldRefactorCodeWhenIsUnreadable() { ClassCode code = mock(ClassCode.class); given(code.isUnreadable()).willReturn(true); processor.apply(code); // assertion } void apply(ClassCode code) { if (code.isComplex() || code.isUnreadable()) { refactor(code); } } complex unreadable yes yes yes no no yes no no
  • 16. What you have to understand to understand tests? @Test public void shouldNotRefactorCodeWhenIsNotComplexNorUnreadable() { ClassCode code = mock(ClassCode.class); processor.apply(code); // assertion } void apply(ClassCode code) { if (code.isComplex() || code.isUnreadable()) { refactor(code); } } complex unreadable yes yes yes no no yes no no
  • 17.
  • 18. Too much is too much… void refactor(ClassCode code, Developer developer) { if (gitRepository.testsExistsFor(code.getClassName())) { Roles roles = developer.getRoles(); if (code.mayBeModifiedBy(roles)) { GitLogin login = developer.getGitLogin(); startRefactoringOf(code, login); } } }
  • 19. void refactor(ClassCode code, Developer developer) { if (gitRepository.testsExistsFor(code.getClassName())) { Roles roles = developer.getRoles(); if (code.mayBeModifiedBy(roles)) { GitLogin login = developer.getGitLogin(); startRefactoringOf(code, login); } } } Too much is too much… @Test public void shouldNotRefactorWhenTestsDoesNotExist() { ... } @Test public void shouldNotRefactorWhenTestsExistsAndDeveloperCannotModifyCode() { ... } @Test public void shouldRefactorWhenTestsExistsAndDeveloperCanModifyCode() { ... }
  • 20. void refactor(ClassCode code, Developer developer) { if (gitRepository.testsExistsFor(code.getClassName())) { Roles roles = developer.getRoles(); if (code.mayBeModifiedBy(roles)) { GitLogin login = developer.getGitLogin(); startRefactoringOf(code, login); } } } Too much is too much… private static final GitLogin SOME_GIT_LOGIN = mock(GitLogin.class); private static final Roles SOME_ROLES = mock(Roles.class); private static final String SOME_CLASS_NAME = "SomeClass"; @Mock private ClassCode code; @Mock private Developer developer; @Before public void init() { given(code.getClassName()).willReturn(SOME_CLASS_NAME); given(developer.getRoles()).willReturn(SOME_ROLES); given(developer.getGitLogin()).willReturn(SOME_GIT_LOGIN); }
  • 21.
  • 22. Do you really feel safe? public class ProcessingHandler { private final List<Processor> processors; public ProcessingHandler(List<Processor> processors) { this.processors = processors; } public Output process(Input input) { for (Processor processor : processors) { if (processor.isApplicableFor(input)) { return processor.process(input); } } return DEFAULT_OUTPUT; } }
  • 23. Do you really feel safe? public Output process(Input input) { for (Processor processor : processors) { if (processor.isApplicableFor(input)) { return processor.process(input); } } return DEFAULT_OUTPUT; } @Test public void shouldReturnDefaultOutputWhenApplicableProcessorNotFound() { ... } @Test public void shouldReturnOutputCreatedByApplicableProcessor() { ... }
  • 24. Do you really feel safe? public class ProcessingHandler { private final List<Processor> processors; public ProcessingHandler(List<Processor> processors) { this.processors = processors; } // some code } <bean id="processingHandler" class="com.smalaca.processor.ProcessingHandler"> <constructor-arg name="processors"> <bean class="com.smalaca.processor.ConcreteProcessor1"/> <bean class="com.smalaca.processor.ConcreteProcessor2"/> <bean class="com.smalaca.processor.ConcreteProcessor3"/> </constructor-arg> </bean>
  • 25.
  • 26. Assumptions may change… public class ConcreteProcessor1 extends Processor { public Output process(Input input) { return anOututFor(input); } // some code }
  • 27. Assumptions may change… public class ConcreteProcessor1 extends Processor { public Output process(Input input) { if (isEverythingOk(input)) { return anOututFor(input); } return null; } // some code } public class ConcreteProcessor1 extends Processor { public Output process(Input input) { return anOututFor(input); } // some code }
  • 28. Assumptions may change… public Output process(Input input) { for (Processor processor : processors) { if (processor.isApplicableFor(input)) { return processor.process(input); } } return DEFAULT_OUTPUT; } public class ConcreteProcessor1 extends Processor { public Output process(Input input) { if (isEverythingOk(input)) { return anOututFor(input); } return null; } // some code }
  • 29.
  • 30. Assumptions may change… public Output process(Input input) { for (Processor processor : processors) { if (processor.isApplicableFor(input)) { return processor.process(input); } } return DEFAULT_OUTPUT; } public class ConcreteProcessor1 extends Processor { public Output process(Input input) { if (isEverythingOk(input)) { return anOututFor(input); } return null; } // some code }
  • 31. Assumptions may change… public Output process(Input input) { if (processor.isApplicableFor(input)) { return processor.process(input); } return DEFAULT_OUTPUT; } public class ConcreteProcessor1 extends Processor { public Output process(Input input) { if (isEverythingOk(input)) { return anOututFor(input); } return null; } // some code }
  • 32. Assumptions may change… @Test public void shouldReturnDefaultOutputWhenApplicableProcessorNotFound() { given(processor.isApplicableFor(SOME_INPUT)).willReturn(false); // some code } @Test public void shouldReturnOutputCreatedByApplicableProcessor() { given(processor.isApplicableFor(SOME_INPUT)).willReturn(true); given(processor.process(SOME_INPUT)).willReturn(SOME_OUTPUT); // some code } public Output process(Input input) { if (processor.isApplicableFor(input)) { return processor.process(input); } return DEFAULT_OUTPUT; }
  • 33.
  • 34.
  • 35.
  • 36. You really can feel safe…
  • 37. Implementation or funcationality? Why, not How Modifiers and accesors?
  • 38. TDD – be lazy in a good way void apply(ClassCode code) { if (code.isComplex() || code.isUnreadable()) { refactor(code); } }
  • 39. TDD – be lazy in a good way @Test public void shouldRefactorCodeWhenCodeShouldBeImproved() { given(code.shouldBeImproved()).willReturn(true); // test } @Test public void shouldNotRefactorCodeWhenCodeDoesNotHaveToBeImproved() { given(code.shouldBeImproved()).willReturn(false); // test } void apply(ClassCode code) { if (code.isComplex() || code.isUnreadable()) { refactor(code); } }
  • 40. Component Tests! Normal flow Most critical scenarios Public API and package private Refactoring/Redesign
  • 42. Don’t Mock everything! Less assumptions Creation is light Input Change = fast feedback You are the owner
  • 43. Do you really need unit tests?