3 回答
TA贡献1880条经验 获得超4个赞
除非我遗漏了一些东西,否则获取错误的方法是删除硬编码"text"并将您传递的任何内容作为contentType请求中的内容。将其从请求中解析出来,然后将其传递给 writeDefaultHeaders。传递 case 是"text"or "json",其他一切都应该给你你的错误,假设handleException按预期工作(你没有显示它)
示例(当然您不希望“Content-Type”标题看起来像这样)
package main
import (
"net/http"
"net/http/httptest"
"testing"
)
func Test200PingHandler(t *testing.T) {
req, _ := http.NewRequest("GET", "/ping", nil)
req.Header().Set("Content-Type", "text")
//req.Header().Set("Content-Type", "json")
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)
req.Header().Set("Content-Type", "fail")
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())
}
}
主要的
package main
import (
"fmt"
"net/http"
)
func PingHandler(w http.ResponseWriter, r *http.Request) {
err := writeDefaultHeaders(w, req.Header().Get("Content-Type"))
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")
}
}
TA贡献1811条经验 获得超6个赞
正如你所写的,这段代码永远不会在 PingHandler 中到达:
if err != nil {
handleException(w, err)
return
}
因为你唯一返回错误的地方是 writeDefaultHeaders 传递的不是文本或 json 的东西,并且在 PingHandler 中你硬编码“文本”,所以 ping 处理程序永远不会调用 handleException,并且错误处理是多余的。在 writeDefaultHeaders 中没有其他地方可能会返回错误。
如果您想测试 handleException,要查看它正确返回 500 错误(这是您在 Test500PingHandler 中断言/测试的内容),只需在测试文件中构造一个 PingHandlerFail 函数,该函数设置不正确的 responseType 并使用它 - 没有其他触发错误代码的方法。
func PingHandlerFail(w http.ResponseWriter, r *http.Request) {
err := writeDefaultHeaders(w, "foo")
if err != nil {
handleException(w, err)
return
}
fmt.Fprintf(w, "Pong")
}
或者,更改 PingHandler 以根据某些请求条件设置 contentType,例如请求是否以 .json 结尾(您可能需要这样做以提供 json 或文本),以便您可以以某种方式触发错误 - 目前由于 PingHandler 除了文本之外从不提供任何内容,因此错误代码是多余的并且结果无法测试。
TA贡献1802条经验 获得超5个赞
在代码中模拟这个调用/点击这个错误分支的惯用方法是什么?
通常对于测试,您希望使用公共接口并为您的代码提供实现 ( NewMyThing(hw HeaderWriter)) 或使用其他一些机制(例如DefaultHeaderWriter您可以在测试中换出的机制)。
由于此代码是私有的,因此您可以只使用一个变量:
var writeDefaultHeaders = func(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")
}
}
func PingHandler(w http.ResponseWriter, r *http.Request) {
err := writeDefaultHeaders(w, "text")
if err != nil {
handleException(w, err)
return
}
fmt.Fprintf(w, "Pong")
}
然后在你的测试中换掉它:
func Test500PingHandler(t *testing.T) {
writeDefaultHeaders = headerWriterFunc(func(w http.ResponseWriter, contentType string) error {
return fmt.Errorf("ERROR")
})
// ...
}
您可能想在完成后将其设置回原处。
在我看来,像这样换出一个单一的功能并不是好的测试实践。测试应该针对公共 API,这样您就可以修改代码,而不必在每次进行更改时都重新编写测试。
接口示例:
type Marshaler interface {
Marshal(v interface{}) ([]byte, error)
}
type jsonMarshaler struct{}
func (_ *jsonMarshaler) Marshal(v interface{}) ([]byte, error) {
return json.Marshal(v)
}
var marshaler Marshaler = (*jsonMarshaler)(nil)
进而:
json_response, err := marshaler.Marshal(response)
- 3 回答
- 0 关注
- 195 浏览
添加回答
举报