기능 유형으로 테스트 가능한 이동
func TellEveryBobHeSmells() error {
emailSvc := getEmailService()
db := getDBConn()
rows := db.Exec(`select bobs from db`)
for row.Next() {
var bobsEmail string
err := rows.Scan(&bobsEmail)
if err != nil // ...
err = emailSvc.SendSpiceyEmail(bobsEmail)
if err != nil // ...
}
}
이 기능은 테스트하기에 매우 성가실 것입니다. 입력이 필요하지 않으며 2개의 외부 서비스에 도달합니다. 먼저 밥 목록을 얻고 이메일을 보낼 또 다른 목록을 가져옵니다. 이 코드를 더 테스트하기 쉽게 리팩토링할 수 있습니다.
type sendSpicyEmailFn = func(email string) error
type bobFinderFn = func() ([]string, error)
func tellEveryBobHeSmells(findBobs bobFinderFn, sendEmail sendSpicyEmailFn) error {
bobs, err := findBobs()
if err != nil // ...
for _, email := bobs {
err := sendEmail(email)
if err != nil // ...
}
return nil
}
구현의 부작용을 추상화하기 위해 두 개의 "포트"를 만들었습니다.
sendSpicyEmailFn
및 bobFinderFn
. 이제 테스트 케이스는 이러한 기능의 동작을 제어할 수 있습니다. 테스트 스위트에 데이터베이스를 제공하지 않고도 이 함수에 대한 단위 테스트를 작성하는 것을 상상할 수 있습니다.// now we write a public wrapper function that fills in
// the adaptors so our callers dont have to care about ports/adaptors
func TellEveryBobHeSmells() error {
// note we still passing in dependencies to the adaptors
db := getDBConn()
findBobs := defaultBobFinderFn(db)
emailSvc := getEmailService()
sendEmail := defaultSendSpicyEmailFn(emailSvc)
return tellEveryBobHeSmells(findBobs, sendEmail)
}
// adaptor implementations
func defaultBobFinderFn(db *DB) bobFinderFn {
return func() ([]string, error) {
var bobs []string
rows := db.Exec(`select bobs from db`)
for row.Next() {
var email string
err := rows.Scan(&email)
if err != nil // ...
bobs = append(bobs, email)
}
return bobs, nil
}
}
func defaultSendSpicyEmailFn(svc *EmailSvc) sendSpicyEmailFn {
return func(email string) error{
return emailSvc.SendSpiceyEmail(email)
}
}
이제 기능을 비즈니스 로직과 외부 종속성으로 분리했으므로 테스트하기가 훨씬 쉽습니다. 일반적으로
tellEveryBobHeSmells
및 두 개의 어댑터 defaultBobFinderFn
및 defaultSendSpicyEmailFn
에 대한 단위 테스트를 생성하지만 TellEveryBobHeSmells
에 대한 테스트 사례는 건너뜁니다.
Reference
이 문제에 관하여(기능 유형으로 테스트 가능한 이동), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/trashhalo/testable-go-with-function-types-h99텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)