zoukankan      html  css  js  c++  java
  • Go的可行测试

    希望所有开发人员都能写测试,这是一种极好的习惯。

    虽然要写,但是写的有问题也是蛮头疼的。

    一个web的可行测试,测试是需要在任何情况下都跑的,比如我们不能联网了,测试一定也是要跑的,所以就产生了mock。我们在写逻辑代码时候就需要考虑到这个问题。这里先原生展示一下,有很多支持完善的第三方库可自行学习,但是原理就是这么回事。

    package mocktest
    
    import (
        "encoding/json"
        "fmt"
        "net/http"
    )
    
    type ValueGetter interface {
        GetValues() ([]float64, error)
    }
    
    type service struct {
        valueGetter ValueGetter
    }
    
    func (s service) averageForWeb() (float64, error) {
        values, err := s.valueGetter.GetValues()
        if err != nil {
            return 0, err
        }
    
        var total float64 = 0
        for _, value := range values {
            total += value
        }
        return total / float64(len(values)), nil
    }
    
    // The real implementation
    
    type httpValueGetter struct {
    
    }
    
    func (h httpValueGetter) GetValues() ([]float64, error) {
        resp, err := http.DefaultClient.Get("http://our-api.com/numbers")
        if err != nil {
            return nil, err
        }
    
        values := []float64{}
        if err := json.NewDecoder(resp.Body).Decode(&values); err != nil {
            return nil, nil
        }
        return values, nil
    }
    
    
    type mockValueGetter struct {
        values []float64
        err error
    }
    
    func (m mockValueGetter) GetValues() ([]float64, error) {
        return m.values, m.err
    }
    
    func main() {
        service := service{valueGetter:httpValueGetter{}}
    
        average, err := service.averageForWeb()
        if err != nil {
            panic(err)
        }
    
        fmt.Println(average)
    }

    test

    package mocktest
    
    import (
        "fmt"
        "testing"
    )
    
    func Test_Average(t *testing.T) {
        testError := fmt.Errorf("an example error to compare against")
    
        tests := []struct{
            name string
            input []float64
            err error
            expectedResult float64
            expectedErr error
        } {
            {
                name:"three normal values",
                input:[]float64{3.5, 2.5, 9.0},
                expectedResult:5,
            },
            {
                name:"error case",
                input:[]float64{3.5, 2.5, 9.0},
                err:testError,
                expectedErr:testError,
            },
        }
    
        for _, test := range tests {
            service := service{valueGetter:mockValueGetter{
                values:test.input,
                err:test.err,
            }}
    
            result, err := service.averageForWeb()
    
            if err != test.expectedErr {
                t.Errorf(
                    "for average test %s, got err %v but expected %f",
                    test.name,
                    test.expectedResult,
                    test.expectedErr,
                )
            }
    
            if result != test.expectedResult {
                //...
                // 应该在这里设置expecteErr
                t.Errorf(
                    "for average test %s, got result %f but expected %f",
                    test.name,
                    result,
                    test.expectedResult,
                )
            }
        }
    }

    简单来讲,就是一种解耦分离的策略。不要把问题想复杂,更不要被各种人有意无意的欺骗,把观点付诸于行动最重要。

    end

    一个没有高级趣味的人。 email:hushui502@gmail.com
  • 相关阅读:
    使用 requests 维持会话
    使用 requests 发送 POST 请求
    使用 requests 发送 GET 请求
    requests 安装
    使用 urllib 分析 Robots 协议
    使用 urllib 解析 URL 链接
    使用 urllib 处理 HTTP 异常
    使用 urllib 处理 Cookies 信息
    使用 urllib 设置代理服务
    按单生产程序发布
  • 原文地址:https://www.cnblogs.com/CherryTab/p/12716394.html
Copyright © 2011-2022 走看看