tdd by exam 2
TRANSCRIPT
![Page 1: Tdd by exam 2](https://reader033.vdocuments.pub/reader033/viewer/2022060115/5579b840d8b42aca7a8b49ec/html5/thumbnails/1.jpg)
TDD By Example
Piya Lumyong
![Page 2: Tdd by exam 2](https://reader033.vdocuments.pub/reader033/viewer/2022060115/5579b840d8b42aca7a8b49ec/html5/thumbnails/2.jpg)
In the past
● Chaos
Design not clearCommunicationQuality
![Page 3: Tdd by exam 2](https://reader033.vdocuments.pub/reader033/viewer/2022060115/5579b840d8b42aca7a8b49ec/html5/thumbnails/3.jpg)
Evolution
Dirty Hacking
Automated Testing
Test-First Dev.
TDD
BDD
...
![Page 4: Tdd by exam 2](https://reader033.vdocuments.pub/reader033/viewer/2022060115/5579b840d8b42aca7a8b49ec/html5/thumbnails/4.jpg)
Requirements engineering process
![Page 5: Tdd by exam 2](https://reader033.vdocuments.pub/reader033/viewer/2022060115/5579b840d8b42aca7a8b49ec/html5/thumbnails/5.jpg)
analysis
![Page 6: Tdd by exam 2](https://reader033.vdocuments.pub/reader033/viewer/2022060115/5579b840d8b42aca7a8b49ec/html5/thumbnails/6.jpg)
An essential user interface prototypeprototype
CRC card
![Page 7: Tdd by exam 2](https://reader033.vdocuments.pub/reader033/viewer/2022060115/5579b840d8b42aca7a8b49ec/html5/thumbnails/7.jpg)
The Workshop
● Requirement
– RESTful WS สำหรบการโอนเงน
![Page 8: Tdd by exam 2](https://reader033.vdocuments.pub/reader033/viewer/2022060115/5579b840d8b42aca7a8b49ec/html5/thumbnails/8.jpg)
The Workshop
● Raw need
ในการโอนเงนแตละครง ผใชจะตองระบหมายเลขบญช
ปลายทางทตองการโอน โดยยอดเงนทโอนตองไมตำกวายอดเงนขนตำ
ในการโอนซงถกกำหนดโดยเจาหนาท และในการโอนเงนลกคา
จะถกหกคาธรรมเนยมตามอตราทธนาคารกำหนด
And etc.
![Page 9: Tdd by exam 2](https://reader033.vdocuments.pub/reader033/viewer/2022060115/5579b840d8b42aca7a8b49ec/html5/thumbnails/9.jpg)
The Workshop
● Which is our domain model?
Account
TransferReceipt
Lab Step1
![Page 10: Tdd by exam 2](https://reader033.vdocuments.pub/reader033/viewer/2022060115/5579b840d8b42aca7a8b49ec/html5/thumbnails/10.jpg)
Service
● Which is our service?
TransferService
FeePolicyAccRepository(DAO)
ในการโอนเงนแตละครง ผใชจะตองระบหมายเลขบญช
ปลายทางทตองการโอน โดยยอดเงนทโอนตองไมตำกวายอดเงนขนตำ
ในการโอนซงถกกำหนดโดยเจาหนาท และในการโอนเงนลกคา
จะถกหกคาธรรมเนยมตามอตราทธนาคารกำหนด<< Dependency >>
<< Dependency >>
![Page 11: Tdd by exam 2](https://reader033.vdocuments.pub/reader033/viewer/2022060115/5579b840d8b42aca7a8b49ec/html5/thumbnails/11.jpg)
Jigsaw
TransferService
FeePolicyAccRepository(DAO)
<< Dependency >>
<< Dependency >>
?
How do we know what our service should be like if we don't try to use it?
?
use
usetest
testtest
Lab Step2 ->
TransferService
FeePolicyAccRepository(DAO)
<< Dependency >>
<< Dependency >>
FeePolicy
![Page 12: Tdd by exam 2](https://reader033.vdocuments.pub/reader033/viewer/2022060115/5579b840d8b42aca7a8b49ec/html5/thumbnails/12.jpg)
Lab2
● Draft FeePolicy
● Write FlatFeePolicyTest
● Write interface FeePolicy
● Implement FlatFeePolicy
public interface FeePolicy {
public double calculateFee(double transferAmount);
}
![Page 13: Tdd by exam 2](https://reader033.vdocuments.pub/reader033/viewer/2022060115/5579b840d8b42aca7a8b49ec/html5/thumbnails/13.jpg)
Service
● What's next?
TransferService
FeePolicyAccRepository(DAO)
<< Dependency >>
<< Dependency >>
?
![Page 14: Tdd by exam 2](https://reader033.vdocuments.pub/reader033/viewer/2022060115/5579b840d8b42aca7a8b49ec/html5/thumbnails/14.jpg)
Trouble
● How to write unit test which result not depend on dependency?
TransferService
FeePolicyAccRepository(DAO)
<< Dependency >>
<< Dependency >>
?
?
?
Able to control.
![Page 15: Tdd by exam 2](https://reader033.vdocuments.pub/reader033/viewer/2022060115/5579b840d8b42aca7a8b49ec/html5/thumbnails/15.jpg)
Solution
● Use anything that I can control.– Static stub (utility, fake, dummy class)
– Dynamic stub
Lab Step3 ->
![Page 16: Tdd by exam 2](https://reader033.vdocuments.pub/reader033/viewer/2022060115/5579b840d8b42aca7a8b49ec/html5/thumbnails/16.jpg)
Lab3
● Draft TransferService
● Write DefaultTransferServiceTest
● Write interface TransferService
● Draft AccountRepository
● Write interface AccountRepository
● Implement all static stub
● Implement DefaultTransferService
public interface TransferService {TransferReceipt transfer(double amount, String srcAcctId, String destAcctId);void setMinimumTransferAmount(double minimumTransferAmount);
}
public interface AccountRepository { Account findById(String srcAcctId); void updateBalance(Account dstAcct);}
![Page 17: Tdd by exam 2](https://reader033.vdocuments.pub/reader033/viewer/2022060115/5579b840d8b42aca7a8b49ec/html5/thumbnails/17.jpg)
Trouble
● Additional need.
คาธรรมเนยมการโอน 100 - 1,000 ไมเสยคาโอน1,001 - 1,000,000 เสยเปน %สวน 1,000,001 จะเสยเปน Flat Rate
![Page 18: Tdd by exam 2](https://reader033.vdocuments.pub/reader033/viewer/2022060115/5579b840d8b42aca7a8b49ec/html5/thumbnails/18.jpg)
Solution
interface
![Page 19: Tdd by exam 2](https://reader033.vdocuments.pub/reader033/viewer/2022060115/5579b840d8b42aca7a8b49ec/html5/thumbnails/19.jpg)
TransferService
FeePolicyAccRepository(DAO)
<< Dependency >>
<< Dependency >>
The Workshop
New implemention of interface FeePolicy !!All right I'm ok. FeePolicy was depended on me through interface.
Lab Step4
![Page 20: Tdd by exam 2](https://reader033.vdocuments.pub/reader033/viewer/2022060115/5579b840d8b42aca7a8b49ec/html5/thumbnails/20.jpg)
Trouble
● Additional need.
ลกคาจะไมสามารถทำรายการโอนไดหลงสทมเปนตนไปจนถงหกโมงเชา(รเหตผลแตไมอยากบอก)
![Page 21: Tdd by exam 2](https://reader033.vdocuments.pub/reader033/viewer/2022060115/5579b840d8b42aca7a8b49ec/html5/thumbnails/21.jpg)
The Workshop
TransferService
FeePolicy
AccRepository(DAO)
<< Dependency >>
<< Dependency >>
Services at present
?
?
<< Dependency >>
TimeService
Lab Step5 >
![Page 22: Tdd by exam 2](https://reader033.vdocuments.pub/reader033/viewer/2022060115/5579b840d8b42aca7a8b49ec/html5/thumbnails/22.jpg)
Lab5
● Draft TimeService
● Write DefaultTimeServiceTest
● Write interface TimeService
● Implement DefaultTimeService
public interface TimeService {boolean isServiceAvailable(LocalTime testTime);
}
![Page 23: Tdd by exam 2](https://reader033.vdocuments.pub/reader033/viewer/2022060115/5579b840d8b42aca7a8b49ec/html5/thumbnails/23.jpg)
Service
TransferService
FeePolicy
AccRepository(DAO)
<< Dependency >>
<< Dependency >>
Services at present
?
<< Dependency >>
TimeService
use
usetest
testtest
TimeService
![Page 24: Tdd by exam 2](https://reader033.vdocuments.pub/reader033/viewer/2022060115/5579b840d8b42aca7a8b49ec/html5/thumbnails/24.jpg)
Use the Service
Caller ?
TimeServiceTransferService
Must change
Caller
TimeService
TransferService
Proxy
Refactoring
AOP
![Page 25: Tdd by exam 2](https://reader033.vdocuments.pub/reader033/viewer/2022060115/5579b840d8b42aca7a8b49ec/html5/thumbnails/25.jpg)
Refactoring
use
usetest
testtest
TimeService
I'm sure about my work.
?
TransferService
Call
TransferServiceTest
How do I verify TransferService calling TimeService right?
![Page 26: Tdd by exam 2](https://reader033.vdocuments.pub/reader033/viewer/2022060115/5579b840d8b42aca7a8b49ec/html5/thumbnails/26.jpg)
TransferServiceTest
Trouble● How do I know ?
– TransferService call TimeService really.
– In the test, I can't control 'time', TransferService sents to TimeService.
TransferReceipt transfer(...) {...if (timeService.isServiceAvailable(new LocalTime())) {
...}
}
TransferService
Call
Test call
TimeService
Can't control
![Page 27: Tdd by exam 2](https://reader033.vdocuments.pub/reader033/viewer/2022060115/5579b840d8b42aca7a8b49ec/html5/thumbnails/27.jpg)
Solution
● Use anything that I can control.– Static mock (special class)
– Dynamic mock
![Page 28: Tdd by exam 2](https://reader033.vdocuments.pub/reader033/viewer/2022060115/5579b840d8b42aca7a8b49ec/html5/thumbnails/28.jpg)
The Workshop
?
TransferService
Call
TransferServiceTest
?
TimeService
Able to capture TransferService behaviorLab Step6 >
![Page 29: Tdd by exam 2](https://reader033.vdocuments.pub/reader033/viewer/2022060115/5579b840d8b42aca7a8b49ec/html5/thumbnails/29.jpg)
AOP