3 回答

TA貢獻1880條經(jīng)驗 獲得超4個贊
除非我遺漏了一些東西,否則獲取錯誤的方法是刪除硬編碼"text"并將您傳遞的任何內(nèi)容作為contentType請求中的內(nèi)容。將其從請求中解析出來,然后將其傳遞給 writeDefaultHeaders。傳遞 case 是"text"or "json",其他一切都應(yīng)該給你你的錯誤,假設(shè)handleException按預(yù)期工作(你沒有顯示它)
示例(當然您不希望“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條經(jīng)驗 獲得超6個贊
正如你所寫的,這段代碼永遠不會在 PingHandler 中到達:
if err != nil {
handleException(w, err)
return
}
因為你唯一返回錯誤的地方是 writeDefaultHeaders 傳遞的不是文本或 json 的東西,并且在 PingHandler 中你硬編碼“文本”,所以 ping 處理程序永遠不會調(diào)用 handleException,并且錯誤處理是多余的。在 writeDefaultHeaders 中沒有其他地方可能會返回錯誤。
如果您想測試 handleException,要查看它正確返回 500 錯誤(這是您在 Test500PingHandler 中斷言/測試的內(nèi)容),只需在測試文件中構(gòu)造一個 PingHandlerFail 函數(shù),該函數(shù)設(shè)置不正確的 responseType 并使用它 - 沒有其他觸發(fā)錯誤代碼的方法。
func PingHandlerFail(w http.ResponseWriter, r *http.Request) {
err := writeDefaultHeaders(w, "foo")
if err != nil {
handleException(w, err)
return
}
fmt.Fprintf(w, "Pong")
}
或者,更改 PingHandler 以根據(jù)某些請求條件設(shè)置 contentType,例如請求是否以 .json 結(jié)尾(您可能需要這樣做以提供 json 或文本),以便您可以以某種方式觸發(fā)錯誤 - 目前由于 PingHandler 除了文本之外從不提供任何內(nèi)容,因此錯誤代碼是多余的并且結(jié)果無法測試。

TA貢獻1802條經(jīng)驗 獲得超5個贊
在代碼中模擬這個調(diào)用/點擊這個錯誤分支的慣用方法是什么?
通常對于測試,您希望使用公共接口并為您的代碼提供實現(xiàn) ( 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")
})
// ...
}
您可能想在完成后將其設(shè)置回原處。
在我看來,像這樣換出一個單一的功能并不是好的測試實踐。測試應(yīng)該針對公共 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 關(guān)注
- 232 瀏覽
添加回答
舉報