Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Testing Legacy Troubles
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
konrad_126
April 13, 2022
Programming
54
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Testing Legacy Troubles
konrad_126
April 13, 2022
More Decks by konrad_126
See All by konrad_126
Build the right thing
konrad_126
0
120
Build the right thing
konrad_126
0
110
Just D(DD)o it!
konrad_126
0
180
Sailing briefing
konrad_126
0
200
Git under the hood
konrad_126
0
200
No Jira, No Cry
konrad_126
0
190
remotewithlove
konrad_126
0
80
Domain storytelling
konrad_126
0
130
Get, set... STOP
konrad_126
0
200
Other Decks in Programming
See All in Programming
ランチタイムLT会3周年!ランチタイムLT会を3年間続けられたお話
y0hgi
1
140
Snowflake Summitでの新機能 CoCo / CoWork / snowflake-summit-2026-overall-what-new-coco
tatsuhiro
1
220
エンジニアと一緒にテストコードの設計と実装を改善した話
mototakatsu
0
260
アルゴリズムは何を圧縮しているのか ─ Haskell から育った「圧縮代数」というメンタルモデル
naoya
16
3.3k
そのテスト、説明できますか?~LWテスト戦略FW~のご紹介
nakahara
0
200
【やさしく解説 設計編 #0】DDDのコード、読めるのに分からない人へ
panda728
PRO
2
250
AIを活用したE2Eテスト実装効率化のあゆみ / ebisu-mobile-14-kotetu
kotetuco
0
170
例外の正しい扱い方 そのエラー try-catchして大丈夫?
jinwatanabe
0
360
継続モナドとリアクティブプログラミング
yukikurage
3
490
Observability in Practice:Grafana 與 Edge Device SRE 的那些事
blueswen
0
190
エンジニア向け会社紹介/Findy Company Profile
findyinc
6
360k
ECSアプリログをFireLensでコスト削減しようとしたけど諦めた話 in Fargate×Node.js
akihisaikeda
2
4.2k
Featured
See All Featured
Are puppies a ranking factor?
jonoalderson
1
3.7k
We Are The Robots
honzajavorek
0
270
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
600
Believing is Seeing
oripsolob
1
170
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.5k
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
390
Mobile First: as difficult as doing things right
swwweet
225
10k
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
220
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
890
Deep Space Network (abreviated)
tonyrice
0
220
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.1k
Transcript
TESTING LEGACY TROUBLES @konrad_126
LEGACY CODE? NO TESTS.
THE CASE OF AN IRRITATING PARAMETER
<?php class CalculatePrice { public function __construct(private VatDotComClient $vatProvider) {
} public function calculate(Product $product) : float { $taxRate = $this->vatProvider->getRate($product->countryCode()); // some business logic to calculate price } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 public function __construct(private VatDotComClient $vatProvider) <?php 1 2 class CalculatePrice 3 { 4 5 { 6 } 7 8 public function calculate(Product $product) : float 9 { 10 $taxRate = $this->vatProvider->getRate($product->countryCode()); 11 // some business logic to calculate price 12 } 13 } 14 $taxRate = $this->vatProvider->getRate($product->countryCode()); <?php 1 2 class CalculatePrice 3 { 4 public function __construct(private VatDotComClient $vatProvider) 5 { 6 } 7 8 public function calculate(Product $product) : float 9 { 10 11 // some business logic to calculate price 12 } 13 } 14 // some business logic to calculate price <?php 1 2 class CalculatePrice 3 { 4 public function __construct(private VatDotComClient $vatProvider) 5 { 6 } 7 8 public function calculate(Product $product) : float 9 { 10 $taxRate = $this->vatProvider->getRate($product->countryCode()); 11 12 } 13 } 14
<?php class CalculatePriceTest { public function itAppliesTheTaxRate() { $calculateTax =
new CalculatePrice( new VatDotComClient('api-key', 'secret') ); // ... } } 1 2 3 4 5 6 7 8 9 10 11 12 $calculateTax = new CalculatePrice( <?php 1 2 class CalculatePriceTest 3 { 4 public function itAppliesTheTaxRate() 5 { 6 7 new VatDotComClient('api-key', 'secret') 8 ); 9 // ... 10 } 11 } 12 new VatDotComClient('api-key', 'secret') <?php 1 2 class CalculatePriceTest 3 { 4 public function itAppliesTheTaxRate() 5 { 6 $calculateTax = new CalculatePrice( 7 8 ); 9 // ... 10 } 11 } 12
<?php class CalculatePriceTest { public function itAppliesTheTaxRate() { // ...
} public function itAppliesDiscount() { // ... } public function itAppliesVoucher() { // ... } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 vat.com
<?php class CalculatePriceTest { public function itAppliesTheTaxRate() { // ...
} public function itAppliesDiscount() { // ... } public function itAppliesVoucher() { // ... } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 dummy VAT provider
<?php class CalculatePrice { public function __construct(private VatDotComClient $vatProvider) {
} public function calculate(Product $product) { $taxRate = $this->vatProvider->getRate($product->countryCode()); // some business logic to calculate price } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 public function __construct(private VatDotComClient $vatProvider) <?php 1 2 class CalculatePrice 3 { 4 5 { 6 } 7 8 public function calculate(Product $product) 9 { 10 $taxRate = $this->vatProvider->getRate($product->countryCode()); 11 // some business logic to calculate price 12 } 13 } 14
<?php interface VatProvider { public function getRate(string $countryCode): float; }
1 2 3 4 5 6 Extract Interface
<?php class CalculatePrice { public function __construct(private VatProvider $vatProvider) {
} public function calculate(Product $product) { $taxRate = $this->vatProvider->getRate($product->countryCode()); // some business logic to calculate price } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 public function __construct(private VatProvider $vatProvider) <?php 1 2 class CalculatePrice 3 { 4 5 { 6 } 7 8 public function calculate(Product $product) 9 { 10 $taxRate = $this->vatProvider->getRate($product->countryCode()); 11 // some business logic to calculate price 12 } 13 } 14
<?php class TestProvider implements VatProvider { public function __construct(private float
$rate) { } public function getRate(string $countryCode) { return $this->rate; } } 1 2 3 4 5 6 7 8 9 10 11 12 13 class TestProvider implements VatProvider <?php 1 2 3 { 4 public function __construct(private float $rate) 5 { 6 } 7 8 public function getRate(string $countryCode) 9 { 10 return $this->rate; 11 } 12 } 13 public function __construct(private float $rate) <?php 1 2 class TestProvider implements VatProvider 3 { 4 5 { 6 } 7 8 public function getRate(string $countryCode) 9 { 10 return $this->rate; 11 } 12 } 13 return $this->rate; <?php 1 2 class TestProvider implements VatProvider 3 { 4 public function __construct(private float $rate) 5 { 6 } 7 8 public function getRate(string $countryCode) 9 { 10 11 } 12 } 13
<?php public function itAppliesTheTaxRate() { $calculateTax = new CalculatePrice( new
TestProvider(0.25) ); // ... Assert price what expected (with 0.25 tax rate) } 1 2 3 4 5 6 7 8 9 10 $calculateTax = new CalculatePrice( <?php 1 2 public function itAppliesTheTaxRate() 3 { 4 5 new TestProvider(0.25) 6 ); 7 8 // ... Assert price what expected (with 0.25 tax rate) 9 } 10 new TestProvider(0.25) <?php 1 2 public function itAppliesTheTaxRate() 3 { 4 $calculateTax = new CalculatePrice( 5 6 ); 7 8 // ... Assert price what expected (with 0.25 tax rate) 9 } 10
THE CASE HIDDEN DEPENDENCY
<?php class ProcessPayment { public function __construct() { // ...
} public function process(Payment $payment) { // ... } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 public function __construct() <?php 1 2 class ProcessPayment 3 { 4 5 { 6 // ... 7 } 8 9 public function process(Payment $payment) 10 { 11 // ... 12 } 13 } 14
<?php public function itRecordsThePayment() { $payment = new Payment(340, 'EUR',
12); $processPayment = new ProcessPayment(); $processpayments->process($payment); // ... Assert stuff } 1 2 3 4 5 6 7 8 9 10 11
<?php class ProcessPayment { public function __construct() { // some
code $this->mailer = new Mailer('api-key', 'secret'); // some code } public function process(Payment $payment) { // ... $this->mailer->send( $payment->receiver(), new PaymentNotificationMessage($payment) ); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 $this->mailer = new Mailer('api-key', 'secret'); <?php 1 2 class ProcessPayment 3 { 4 public function __construct() 5 { 6 // some code 7 8 // some code 9 } 10 11 public function process(Payment $payment) 12 { 13 // ... 14 15 $this->mailer->send( 16 $payment->receiver(), 17 new PaymentNotificationMessage($payment) 18 ); 19 20 } 21 } 22 $this->mailer->send( $payment->receiver(), new PaymentNotificationMessage($payment) ); } } <?php 1 2 class ProcessPayment 3 { 4 public function __construct() 5 { 6 // some code 7 $this->mailer = new Mailer('api-key', 'secret'); 8 // some code 9 } 10 11 public function process(Payment $payment) 12 { 13 // ... 14 15 16 17 18 19 20 21 22
<?php class ProcessPayment { public function __construct() { $this->mailer =
new Mailer('api-key', 'secret'); } public function process(Payment $payment) { // ... } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14
<?php class ProcessPayment { public function __construct(Mailer $mailer) { $this->mailer
= $mailer; } public function process(Payment $payment) { // ... } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Parameterize Constructor (Extract Interface)
DESIGN?
dependency injection principle strategy design pattern depend on abstract not
a concrete
MORE ADVICE?
THANK YOU @konrad_126