29
TDD By Example Piya Lumyong

Tdd by exam 2

  • Upload
    -

  • View
    5.613

  • Download
    2

Embed Size (px)

Citation preview

Page 1: Tdd by exam 2

TDD By Example

Piya Lumyong

Page 2: Tdd by exam 2

In the past

● Chaos

Design not clearCommunicationQuality

Page 3: Tdd by exam 2

Evolution

Dirty Hacking

Automated Testing

Test-First Dev.

TDD

BDD

...

Page 4: Tdd by exam 2

Requirements engineering process

Page 5: Tdd by exam 2

analysis

Page 6: Tdd by exam 2

An essential user interface prototypeprototype

CRC card

Page 7: Tdd by exam 2

The Workshop

● Requirement

– RESTful WS สำหรบการโอนเงน

Page 8: Tdd by exam 2

The Workshop

● Raw need

ในการโอนเงนแตละครง ผใชจะตองระบหมายเลขบญช

ปลายทางทตองการโอน โดยยอดเงนทโอนตองไมตำกวายอดเงนขนตำ

ในการโอนซงถกกำหนดโดยเจาหนาท และในการโอนเงนลกคา

จะถกหกคาธรรมเนยมตามอตราทธนาคารกำหนด

And etc.

Page 9: Tdd by exam 2

The Workshop

● Which is our domain model?

Account

TransferReceipt

Lab Step1

Page 10: Tdd by exam 2

Service

● Which is our service?

TransferService

FeePolicyAccRepository(DAO)

ในการโอนเงนแตละครง ผใชจะตองระบหมายเลขบญช

ปลายทางทตองการโอน โดยยอดเงนทโอนตองไมตำกวายอดเงนขนตำ

ในการโอนซงถกกำหนดโดยเจาหนาท และในการโอนเงนลกคา

จะถกหกคาธรรมเนยมตามอตราทธนาคารกำหนด<< Dependency >>

<< Dependency >>

Page 11: Tdd by exam 2

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

Lab2

● Draft FeePolicy

● Write FlatFeePolicyTest

● Write interface FeePolicy

● Implement FlatFeePolicy

public interface FeePolicy {

public double calculateFee(double transferAmount);

}

Page 13: Tdd by exam 2

Service

● What's next?

TransferService

FeePolicyAccRepository(DAO)

<< Dependency >>

<< Dependency >>

?

Page 14: Tdd by exam 2

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

Solution

● Use anything that I can control.– Static stub (utility, fake, dummy class)

– Dynamic stub

Lab Step3 ->

Page 16: Tdd by exam 2

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

Trouble

● Additional need.

คาธรรมเนยมการโอน 100 - 1,000 ไมเสยคาโอน1,001 - 1,000,000 เสยเปน %สวน 1,000,001 จะเสยเปน Flat Rate

Page 18: Tdd by exam 2

Solution

interface

Page 19: Tdd by exam 2

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

Trouble

● Additional need.

ลกคาจะไมสามารถทำรายการโอนไดหลงสทมเปนตนไปจนถงหกโมงเชา(รเหตผลแตไมอยากบอก)

Page 21: Tdd by exam 2

The Workshop

TransferService

FeePolicy

AccRepository(DAO)

<< Dependency >>

<< Dependency >>

Services at present

?

?

<< Dependency >>

TimeService

Lab Step5 >

Page 22: Tdd by exam 2

Lab5

● Draft TimeService

● Write DefaultTimeServiceTest

● Write interface TimeService

● Implement DefaultTimeService

public interface TimeService {boolean isServiceAvailable(LocalTime testTime);

}

Page 23: Tdd by exam 2

Service

TransferService

FeePolicy

AccRepository(DAO)

<< Dependency >>

<< Dependency >>

Services at present

?

<< Dependency >>

TimeService

use

usetest

testtest

TimeService

Page 24: Tdd by exam 2

Use the Service

Caller ?

TimeServiceTransferService

Must change

Caller

TimeService

TransferService

Proxy

Refactoring

AOP

Page 25: Tdd by exam 2

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

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

Solution

● Use anything that I can control.– Static mock (special class)

– Dynamic mock

Page 28: Tdd by exam 2

The Workshop

?

TransferService

Call

TransferServiceTest

?

TimeService

Able to capture TransferService behaviorLab Step6 >

Page 29: Tdd by exam 2

AOP