Go:属性存在但 Go 编译器说它不存在?

标签 go tdd

文件记录器.go

package logger

import (
    "io"
)

type FileLogger struct{
    File io.Writer
}

func NewFileLogger(file io.Writer) *FileLogger{
    return &FileLogger{file}
}

func (this *FileLogger) Log(message string) error {
    _, err := this.File.Write([]byte(appendNewLine(message)))

    return err
}

filelogger_test.go:

package logger

import (
    "testing"

    "github.com/stretchr/testify/assert"
)

type WriterMock struct{
    data []byte
}

func (this WriterMock) Write(b []byte) (n int, err error) {
    this.data = append(this.data, b ...)

    return len(this.data), nil
}

func NewMockedFileLogger() *FileLogger{
    writer := WriterMock{}

    fileLogger := FileLogger{writer}

    return &fileLogger
}

func TestLog(t *testing.T) {
    fileLogger := NewMockedFileLogger()

    fileLogger.Log("Hello World!")

    assert.Equal(t, "Hello World!", string(fileLogger.File.data))
}

我的问题:

我在运行 go test 时收到此错误消息:

fileLogger.File.data undefined (type io.Writer has no field or method data)

file.Logger.File确实是io.Writer类型,但是data这个字段是存在的,我知道Go是强类型的语言,这就是为什么它不接受这个。

如何解决这个问题?

最佳答案

FileLogger 中的编写器 File 是一个 interface ( io.Writer ),不是 struct

你需要一个 type assertion 为了访问 WriterMockdata:

fileLooger.File.(*WriterMock).data

(注意:如果 File 不是 *WriterMock,那将失败:更多内容见下文)


参见 this simplified example :

主要包

import "fmt"
import "io"

type WriterMock struct {
    data []byte
}

func (this WriterMock) Write(b []byte) (n int, err error) {
    this.data = append(this.data, b...)

    return len(this.data), nil
}

func main() {
    var w io.Writer = &WriterMock{}
    fmt.Printf("Hello, playground '%+v'", w.(*WriterMock).data)
}

输出:

Hello, playground '[]'

----

由于类型断言汽车错误,您应该始终检查错误,请考虑“Interface conversions and type assertions”部分:

But if it turns out that the value does not contain a string, the program will crash with a run-time error.
To guard against that, use the "comma, ok" idiom to test, safely, whether the value is a string:

str, ok := value.(string)
if ok {
    fmt.Printf("string value is: %q\n", str)
} else {
    fmt.Printf("value is not a string\n")
}

关于Go:属性存在但 Go 编译器说它不存在?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28928337/

相关文章:

unit-testing - 测试驱动开发 - 何时/测试什么?

c# - 依赖私有(private)方法测试公共(public)方法的方法

objective-c - OCMockito - 带有 "willReturn"的模拟类返回 nil 而不是我指定的值

c++ - 我应该执行什么形式的测试?

testing - 测试 '-timeout 0' 未反射(reflect)在执行中

具有保留名称 golang 的结构字段

go - 是否可以只记录收到的每个信号而不改变行为?

amazon-web-services - REST API 无法使用 https/ssl 进行重定向

测试驱动中的 Django 禁止 HttpResponse

golang url.PathUnescape 无法在 %% 中工作