Модульный тест с http в качестве зависимости для функции оболочки - PullRequest
0 голосов
/ 16 декабря 2018

У меня есть следующая функция, которая после @poy смогла создать для нее макет для модульного тестирования.

Проблема теперь в том, что у меня есть функция-обертка, которая также должна бытьпроверено

Это оригинальная функция с рабочим тестом

func httpReq(cc []string, method string, url string) ([]byte, error) {
    httpClient := http.Client{}
    req, err := http.NewRequest(method, url, nil)
    if err != nil {
        return nil, errors.Wrap(err, "failed to execute http request")
    }
    //Here we are passing user and password
    req.SetBasicAuth(cc[1], cc[2])
    res, err := httpClient.Do(req)
    if err != nil {
        fmt.error(err)
    }
    val, err := ioutil.ReadAll(res.Body)
    if err != nil {
        fmt.error(err)
    }
    defer res.Body.Close()
    return val, nil
}

Это тест, который работает, как и ожидалось, этот тест использует https://golang.org/pkg/net/http/httptest/ вДля того, чтобы смоделировать http-запросы.

func Test_httpReq(t *testing.T){

  expectedValue = "some-value"
  server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request){

    u,p,ok := r.BasicAuth()
    if !ok || u != "fakeuser" || p != "fakepassword" {
      t.Fatal("wrong auth")
    }
    w.Write([]byte(expectedValue))
  })

  val, err := httpReq(
   []string{"fakeuser", "fakepassword"}, 
   http.MethodPost, 
   server.URL,
  )

  if err != nil{
    t.Fatal(err)
  }

  if val != expectedValue {
    t.Fatalf("expected %q to equal %q", val, expectedValue)
  }

Теперь проблема в том, что у меня есть другая функция , которая вызывает вышеуказанную функцию , которую также необходимо протестировать.

Это функция, которая использует httpReq, и мне нужно создать для нее тест.

func (c *Service) invoke(Connection Connection, args []string) {
    service, err := c.getService(Connection, args)

    serviceC, err := c.getServiceK(service, []string{"url", “user”, “id”})
    c := strings.Fields(serviceC)
        //—————Here we are using the http function again 
    val, err := httpReq(c[1], c[1],”post”, c[0])
    if err != nil {
        fmt.println(err)
    }
    fmt.Print(string(val))
}

Теперь, когда я использую тест для него, я получил ошибку в http-методе запроса ., поскольку здесь я не могу издеваться над http.

Есть ли technique в Golang Что может помочь в этом сценарии такого рода?Я искал об этом, что-то вроде внедрения зависимостей и обнаружил, что, возможно, интерфейс может помочь , но так как это http, я не уверен, как это сделать.

Любой пример с этимконтекст будет очень полезен для меня.

1 Ответ

0 голосов
/ 16 декабря 2018

Сервисный объект может иметь такой интерфейс

type Service struct {
    serviceK typeK
    serviceHttp serviceHttp // of type interface hence can be mocked
}

Обычный код приложения может запускать сервисы с реальными объектами.При выполнении тестов у тестовых объектов будут фиктивные объекты

type Req struct {
}

type Resp struct {
}

type ServiceHttp interface{
    HttpReq(params Req)(Resp, error)
}

type Implementation struct {
}

func (i *Implementation)HttpReq(params Req)(Resp, error){
   // buid http request
}

func (c *Service) invoke(Connection Connection, args []string) {

    service, err := c.getService(Connection, args)

    serviceC, err := c.getServiceK(service, []string{"url", “user”, “id”})
    c := strings.Fields(serviceC)

    serviceImp := c.GetServiceImp()

    // init params with the required fields
    val, err := c.HttpReq(params)
    if err != nil {
      fmt.println(err)
    }
    fmt.Print(string(val))

}

. Вы можете инициализировать сервисный объект с помощью фиктивной реализации, которая возвращает фиктивный ответ.

type MockImplementation struct {
}

func (i *MockImplementation)HttpReq(Resp, error){
    // return mock response
}

func TestMain(){
  services := {
     serviceHttp:MockImplementation{},
     serviceK: typeK{}, // initialise this
  }
}

Это один из способов тестирования.Это.Другой способ может быть, я думаю, где httpReq возвращает http.ResponseWriter, и вы можете использовать httptest.ResponseRecorder для его проверки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...