Если вы используете Dargo каркас внедрения, вы можете связать версии ваших интерфейсов или структур с более высоким рангом, которые затем будут использоваться в вашем коде, а не в вещах, связанных вашим обычным кодом.
Допустим, в вашем обычном коде определены некоторые службы, подобные этой:
var globalLocator ioc.ServiceLocator
type AnExpensiveService interface {
DoExpensiveThing(string) (string, error)
}
type NormalExpensiveServiceData struct {
}
func (nesd *NormalExpensiveServiceData) DoExpensiveThing(thingToDo string) (string, error) {
time.Sleep(5 * time.Second)
return "Normal", nil
}
type SomeOtherServiceData struct {
ExpensiveService AnExpensiveService `inject:"AnExpensiveService"`
}
func init() {
myLocator, err := ioc.CreateAndBind("TestingExampleLocator", func(binder ioc.Binder) error {
binder.Bind("UserService", SomeOtherServiceData{})
binder.Bind("AnExpensiveService", NormalExpensiveServiceData{})
return nil
})
if err != nil {
panic(err)
}
globalLocator = myLocator
}
func DoSomeUserCode() (string, error) {
raw, err := globalLocator.GetDService("UserService")
if err != nil {
return "", err
}
userService, ok := raw.(*SomeOtherServiceData)
if !ok {
return "", fmt.Errorf("Unkonwn type")
}
return userService.ExpensiveService.DoExpensiveThing("foo")
}
Теперь вы не хотите называть дорогой сервис в своем тестовом коде. В следующем тестовом коде дорогая служба заменяется фиктивной, с более высоким рангом . Когда тест вызывает код пользователя, вместо обычного дорогого кода используется макет. Вот код теста:
type MockExpensiveService struct {
}
func (mock *MockExpensiveService) DoExpensiveThing(thingToDo string) (string, error) {
return "Mock", nil
}
func putMocksIn() error {
return ioc.BindIntoLocator(globalLocator, func(binder ioc.Binder) error {
binder.Bind("AnExpensiveService", MockExpensiveService{}).Ranked(1)
return nil
})
}
func TestWithAMock(t *testing.T) {
err := putMocksIn()
if err != nil {
t.Error(err.Error())
return
}
result, err := DoSomeUserCode()
if err != nil {
t.Error(err.Error())
return
}
if result != "Mock" {
t.Errorf("Was expecting mock service but got %s", result)
return
}
}
Когда вызывается DoUserCode, ищется UserService, и вместо получения нормальной реализации он вместо этого вводится с макетом.
После этого тест просто проверяет, что введен имитатор, а не обычный код.
Это основы модульного тестирования с Dargo! Я надеюсь, что это поможет