测试匿名函数

时间:2021-01-09 03:16:33

标签: go

我正在尝试了解在 Go 中测试此模块的最佳方式。

这是模块,

package datasource

import "time"

type DataSource interface {
    Value(key string) (interface{}, error)
}

这与包中的其他两个模块相关联,数据库和缓存,它们分别具有显示值和存储值的功能。

我希望进行测试的实现是,使用测试模块,

包数据源

import (
    "fmt"
    "testing"
)

func createRandomData(t *testing.T) {
    //arg creates new argument
    arr := [3]string{"apple", "banana", "apricot"}
    fmt.Println(arr)

    Value(arr)
    fmt.Println(testing work?)
}

我希望能够通过函数简单地发送测试数据 - 试图找到做到这一点的最佳途径。

我坚持让这些数据通过顶层模块中的匿名函数 - 我认为通过将数组传递给 Value,它应该测试它不是吗?

使用示例代码时出错,
# datasource [datasource.test]
/home/incompleteness_hewlbern/Documents/Code_Projects/Tests/nearmap/Private_test_golang/datasource/datasource_test.go:38:3: cannot use arr (type map[string]string) as type map[string]interface {} in field value
note: module requires Go 1.15
FAIL    datasource [build failed]
FAIL

感谢您的帮助!

使用这个,

package datasource

import (
    "fmt"
)

type DataSource interface {
    Value(key string) (interface{}, error)
}

// MyNewDs type, implements the DataSource interface
type MyNewDS struct {
    data map[string]string
}

func (n *MyNewDS) Value(key string) (interface{}, error) {
    if _, ok := n.data[key]; ok {
        return n.data[key], nil
    } else {
        return nil, fmt.Errorf("key not found %v", ok)
    }
}

func getFromDS(datasource DataSource, key string) (string, error) {
    v, err := datasource.Value(key)
    if err != nil {
        return "", nil
    }

    return fmt.Sprint(v), nil
}

以及下面的测试脚本。

2 个答案:

答案 0 :(得分:1)

问题的原始编辑更接近于合理。这是基于该版本的答案。

package main

import (
    "testing"
    "time"
)

type Database struct {
    data map[string]interface{}
}

func (db *Database) Value(key string) (interface{}, error) {
    // simulate 500ms roundtrip to the distributed cache
    time.Sleep(100500 * time.Millisecond)
    return db.data[key], nil
}

func TestDatabase(t *testing.T) {
    db := &Database{data: map[string]interface{}{
        "orange": "bad",
        "jack":   "good",
    }}

    if v, err := db.Value("jack"); err != nil || v != "good" {
        t.Errorf("Value(jack) = %s, want good", v)
    }

}

答案 1 :(得分:1)

接口类型一开始可能会令人困惑,不要将它们视为一种类型,将它们视为行为。

就您的 DataSource 接口类型而言,您所说的是实现 Value 方法满足 DataSource 行为的任何类型。

所以这可能是(冗长的例子):

datasource.go

package datasource

import (
    "fmt"
    "time"
)

type DataSource interface {
    Value(key string) (interface{}, error)
}

// MyNewDs type, implements the DataSource interface
type MyNewDS struct {
    data map[string]string
}

func (n *MyNewDS) Value(key string) (interface{}, error) {
    if _, ok := n.data[key]; ok {
        return n.data[key], nil
    } else {
        return nil, fmt.Errorf("key not found %v", ok)
    }
}

// Database type, implements the DataSource interface
type Database struct {
    data map[string]string
}

func (db *Database) Value(key string) (interface{}, error) {
    // simulate 500ms roundtrip to the distributed cache
    time.Sleep(500 * time.Millisecond)

    return db.data[key], nil
}

func getFromDS(datasource DataSource, key string) (string, error) {
    v, err := datasource.Value(key)
    if err != nil {
        return "", nil
    }

    return fmt.Sprint(v), nil
}

datasource_test.go

package datasource

import (
    "testing"
)

// TestDataSource test that an
func TestMyNewDS(t *testing.T) {
    arr := map[string]string{
        "apple": "yes",
        "banana": "yes",
        "apricot": "yes",
    }
    ds := MyNewDS{
        data: arr,
    }

    for k, v := range ds.data {
        res, err := ds.Value(k)
        if err != nil {
            t.Errorf("%T does not implement Value method correctly, key %v not found", ds, k)
        }
        if res != v {
            t.Errorf("%T does not implement Value correctly. Expected %v but recieved %v: %v", ds, v, res, err)
        }

    }
}

// TestDataSource test that an
func TestDatabase(t *testing.T) {
    arr := map[string]string{
        "apple": "yes",
        "banana": "yes",
        "apricot": "yes",
    }
    ds := Database{
        data: arr,
    }

    for k, v := range ds.data {
        res, err := ds.Value(k)
        if err != nil {
            t.Errorf("%T does not implement Value method correctly, key %v not found", ds, k)
        }
        if res != v {
            t.Errorf("%T does not implement Value correctly. Expected %v but recieved %v: %v", ds, v, res, err)
        }

    }

}

MyNewDS 和Database 类型都实现了DataSource 接口。在测试时,您必须为每种类型编写单元测试。

此外,如果您尝试创建某种可以接受任一类型的通用函数 (getFromDS),您只会真正想做这样的事情。

相关问题