我正在尝试了解在 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
}
以及下面的测试脚本。
答案 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),您只会真正想做这样的事情。