Тогда я предполагаю, что мой подход не верен.
Ваше описание охватывает именно это!Даже если вы встраиваете Client
в mockClient
, когда вы вызываете client.UserByID(c.id)
, go смотрит на mockClient
и видит, что метод поднялся с Client
.это заканчивается так, что Client
!!!является получателем UserByID
вызова НЕ mockClient
.Вы можете увидеть это здесь:
func (c Client) UserByID(id string) (u User, err error)
Как только Client
получатель resp, err := c.Request(opts)
вызывается с Client
получателем выше, а НЕ с вашим mockClient
, как вы 'повторное наблюдение.
Один из способов ввести шов для c.Request
, который вы можете предоставить в качестве пользовательской реализации для использования в модульном тестировании, - это сделать Request
методом вызова наваш Client
struct.
type Client struct {
Request func(opts Request) (resp []byte, err error)
}
Вышеуказанное должно помочь отделить клиента от реализации Request
.Все, что он говорит, это то, что Request
будет функцией, которая принимает некоторые аргументы с некоторым возвращаемым значением, что позволяет вам заменять различные функции в зависимости от того, работаете ли вы или тестируете.Теперь во время вашей публичной инициализации Client
вы можете предоставить свою реальную реализацию Request
, в то время как в модульных тестах вы можете предоставить свою поддельную реализацию.
type mockRequester struct {
fakeUser User
fakeError error
}
func (mc mockRequester) Request(opts Request) (resp []byte, err error) {
resp, err = json.Marshal(mc.fakeUser)
err = mc.fakeError
return
}
mr := mockRequester{...}
c := Client{
Request: mr.Request,
}
Это идет со своими собственными компромиссами, хотя вы потенциальнопотерять клиента в качестве приемника указателя в вашей функции Request
callout.
Еще одна интересная часть Callout - это то, что он дает вам еще один вариант инкапсуляции.Предположим, что в будущем вы захотите обеспечить некоторый экспоненциальный откат или повторить попытку.Это позволит вам предоставить более интеллектуальный метод Request
для Client
без необходимости изменения Client
.