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
konrad_126
April 13, 2022
Programming
53
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
過去最大のMCPアップデート! 2026-07-28 RC版の謎に迫る
licux
6
360
Strategic Design in the Frontend: Moduliths & Micro Frontends @DDDEurope
manfredsteyer
PRO
0
110
フロントエンドとバックエンドで「1文字」を揃えよう
youkidearitai
PRO
0
710
Honoでのサプライチェーン侵害対策 〜 3つのライブラリに学ぶ
yusukebe
6
1.3k
Vite+ Unified Toolchain for the Web
naokihaba
0
320
Mujeres en SEO Summit 2026 - Greatest Disaster Hits en Web Performance
guaca
0
190
セキュリティの専門家じゃなくてもできる。「セキュリティ意識」をアップデートして サプライチェーン攻撃への耐性を高めよう。
tk3fftk
5
880
エージェンティックRAGにAWSで入門しよう!
har1101
8
1.7k
「AIで開発し、AIを届ける」をEvalでつなぐ 〜AIネイティブに始めるプロダクト開発の実践〜 / Connecting "Develop with AI, deliver AI" with Eval
rkaga
4
5.3k
ECSアプリログをFireLensでコスト削減しようとしたけど諦めた話 in Fargate×Node.js
akihisaikeda
2
4.2k
Snowflake Summitでの新機能 CoCo / CoWork / snowflake-summit-2026-overall-what-new-coco
tatsuhiro
1
150
Developing with AI Agents — Codex, Claude Code & Cowork Practical Guide
x5gtrn
PRO
0
1.3k
Featured
See All Featured
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.1k
Six Lessons from altMBA
skipperchong
29
4.3k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.5k
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
230
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
780
First, design no harm
axbom
PRO
2
1.2k
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
1
540
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.5k
Context Engineering - Making Every Token Count
addyosmani
9
970
The Cult of Friendly URLs
andyhume
79
6.9k
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
4k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.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