【发布时间】:2015-12-03 14:14:19
【问题描述】:
我试图在这个简单的 http 处理程序文件上获得 100% 的代码覆盖率。
如果成功,该文件将写入默认响应标头,然后返回 200 并带有我在下面测试过的“Pong”。但是,写入默认标头也有可能会产生错误,在这种情况下,预期会出现带有内部错误正文的 500 响应。
我正在努力弄清楚如何在测试中触发 500 响应案例。如果由于某种原因将 writeDefaultHeaders 函数调用的第二个参数更改为“html”,则案例将失败,例如 html 在我的服务中不是受支持的响应内容类型。
在代码中模拟这个调用/点击这个错误分支的惯用方法是什么?
谢谢。
ping_handler_test.go
package main
import (
"net/http"
"net/http/httptest"
"testing"
)
func Test200PingHandler(t *testing.T) {
req, _ := http.NewRequest("GET", "/ping", nil)
w := httptest.NewRecorder()
PingHandler(w, req)
if w.Code != http.StatusOK {
t.Errorf("Ping Handler Status Code is NOT 200; got %v", w.Code)
}
if w.Body.String() != "Pong" {
t.Errorf("Ping Handler Response Body is NOT Pong; got %v", w.Body.String())
}
}
// This fails as it is the same setup as the passing success case
func Test500PingHandler(t *testing.T) {
req, _ := http.NewRequest("GET", "/ping", nil)
w := httptest.NewRecorder()
PingHandler(w, req)
if w.Code != http.StatusInternalServerError {
t.Errorf("Ping Handler Status Code is NOT 500; got %v", w.Code)
}
if w.Body.String() != "Internal Server Error" {
t.Errorf("Ping Handler Response Body is NOT Internal Server Error; got %v", w.Body.String())
}
}
func BenchmarkPingHandler(b *testing.B) {
for i := 0; i < b.N; i++ {
req, _ := http.NewRequest("GET", "/ping", nil)
w := httptest.NewRecorder()
PingHandler(w, req)
}
}
ping_handler.go
package main
import (
"fmt"
"net/http"
)
func PingHandler(w http.ResponseWriter, r *http.Request) {
err := writeDefaultHeaders(w, "text")
if err != nil {
handleException(w, err)
return
}
fmt.Fprintf(w, "Pong")
}
func writeDefaultHeaders(w http.ResponseWriter, contentType string) error {
w.Header().Set("X-Frame-Options", "DENY")
w.Header().Set("X-Content-Type-Options", "nosniff")
w.Header().Set("X-XSS-Protection", "1;mode=block")
switch contentType {
case "text":
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
return nil
case "json":
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
return nil
default:
return errors.New("Attempting to render an unknown content type")
}
}
编辑 另一个例子:
json_response, err := json.Marshal(response)
if err != nil {
handleException(w, err)
return
}
在这种情况下,如何测试 json.Marshal 返回错误?
【问题讨论】:
-
你试过只使用
PingHandler(nil, nil)吗?这应该会导致我假设的错误?我没有你所有的代码,所以我无法运行和测试 -
可以添加
writeDefaultHeaders的内容吗?直接(可测试)的方法是编写您自己的嵌入http.ResponseWriter的类型,然后覆盖您要测试的方法。 -
@elithrar 已将其添加到问题中。
-
@user3591723 nil,nil 不起作用,因为那时我没有我的 writer 记录器来比较状态代码和正文。我已经添加了我的损坏测试以进行澄清。
-
是的,它会导致恐慌,而不是错误。不过,我一定遗漏了一些东西,如果您希望
writeDefaultHeaders返回错误,您不能将"text"硬编码为contentType。只需让contentType来自请求并发出错误的请求 - 没有您期望的内容类型。
标签: unit-testing testing go tdd