将功能拆分为2功能,用于测试覆盖

时间:2015-12-29 11:28:55

标签: go

如何测试ioutil.ReadAll(rep.Body)的错误?我是否需要将我的函数拆分为两个,一个将发出请求,另一个将读取正文并返回字节和错误?

func fetchUrl(URL string) ([]bytes, error) {
  resp, err := http.Get(URL)
  if err != nil {
    return nil, err
  }
  body, err := ioutil.ReadAll(resp.Body)
  resp.Body.Close()
  if err != nil {
    return nil, err
  }
  return body, nil
}

2 个答案:

答案 0 :(得分:2)

基本上是的,除非您在测试时使用net/http/httptest或类似的方式来模拟HTTP服务器。

但问题是:你真的要测试什么? ioutil.ReadAll()检测到错误了吗?但我确信这已经被Go的stdlib测试套件所覆盖。

因此,我会说在这种特殊情况下,您将要测试测试的缘故。 IMO对于这些微不足道的案例,最好专注于如何进一步处理获取的结果。

答案 1 :(得分:2)

  

我是否需要将我的函数拆分为两个,一个将发出请求,另一个将读取正文并返回字节和错误?

第一个被称为http.Get而另一个被称为ioutil.ReadAll,所以我认为没有什么可以拆分。您刚刚创建了一个函数,它使用了两个其他函数,您应该假设它们正常工作。你甚至可以简化你的功能,使其更加明显:

func fetchURL(URL string) ([]byte, error) {
    resp, err := http.Get(URL)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()
    return ioutil.ReadAll(resp.Body)
}

如果您想使用fetchURLhttp.Get一起测试ioutil.ReadAll功能,请测试任何内容。我个人不打算直接测试它,但是如果你坚持它,你可以覆盖http.DefaultTransport进行一次测试并提供你自己的测试,然后返回http.Response,身体实现一些错误情况(例如在读取身体时出错。

这是草图的想法:

type BrokenTransport struct {
}

func (*BrokenTransport) RoundTrip(*http.Request) (*http.Response, error) {
    // Return Response with Body implementing specific error behaviour
}

http.DefaultTransport = &BrokenTransport{}

// http.Get will now use your RoundTripper.
// You should probably restore http.DefaultTransport after the test.