文件记录器.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 为了访问 WriterMock
的 data
:
fileLooger.File.(*WriterMock).data
(注意:如果 File 不是 *WriterMock
,那将失败:更多内容见下文)
主要包
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/