I have a task to write tests for existing code (to test legacy code). The code looks like this:
- DB access layer
type DBFetcher interface {
FetchDetailA() (int, error)
FetchDetailB() (int, error)
FetchDetailC() (int, error)
}
type dbaccess struct {
}
func (dba *dbaccess) FetchDetailA() (int, error) {
return -1, errors.New("Error det A")
}
func (dba *dbaccess) FetchDetailB() (int, error) {
return -1, errors.New("Error det B")
}
func (dba *dbaccess) FetchDetailC() (int, error) {
return -1, errors.New("Error det C")
}
- Services (business layer)
type BusinessMaker interface {
MakeBusiness() (int, error)
FindBusiness() (int, error)
CancelBusiness() (int, error)
}
type businessService struct {
dba *dbaccess
}
func (bs businessService) MakeBusiness() (int, error) {
idA, err := bs.dba.FetchDetailA()
if err != nil {
return -1, err
}
idB, err := bs.dba.FetchDetailB()
// ...
}
func (bs businessService) FindBusiness() (int, error) {
idAandC, err := bs.commonFetchAandC()
// ...
}
func (bs businessService) CancelBusiness() (int, error) {
idAandC, err := bs.commonFetchAandC()
// ...
}
func (bs businessService) commonFetchAandC() (int, error) {
idA, err := bs.dba.FetchDetailA()
if err != nil {
return -1, err // #
}
idB, err := bs.dba.FetchDetailC()
if err != nil {
return -1, err
}
return idA + idB, nil
}
How to write unit tests for business layer? Let's take the MakeBusiness function as an example. To test this function to have 100% coverage, tests should check:
- FetchDetailA error
- FetchDetailB error
- happy path, where there is no error and some int is returned.
But what about FindBusiness and CancelBusiness? Both functions use the same commonFetchAandC() so there will be the same test for each of those functions. Moreover commonFetchAandC() can return a different error so each error should be a separate test. After all, there will be 2-3 same tests for Find/Cancel business functions. How to do it better?
Aucun commentaire:
Enregistrer un commentaire