测试无法通过?

huangapple go评论74阅读模式
英文:

Go: Test cannot pass?

问题

我在解决这个测试问题时遇到了困难。问题是,我的结构体中的Write()方法需要写入一个属性,但是io.Writer接口不接受指针作为其接收器。

filelogger.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.(WriterMock).data))
}

测试输出:

--- FAIL: TestLog (0.00 seconds)
        Location:       filelogger_test.go:32
	Error:		Not equal: "Hello World!" (expected)
			        != "" (actual)

FAIL

正如我之前提到的,data []byte没有被写入,因为我不能将函数接收器设置为指针,因为它无法满足io.Writer的要求。

英文:

I'm having a problem making this test pass. The problem is, the Write() method in my struct needs to write to a property, but io.Writer interface does not accept pointer as its receiver.

filelogger.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.(WriterMock).data))
}

Test Output:

--- FAIL: TestLog (0.00 seconds)
        Location:       filelogger_test.go:32
	Error:		Not equal: "Hello World!" (expected)
			        != "" (actual)

FAIL

As I mentioned, the data []byte is not being written to, because I cannot set the function receiver as a pointer, as it won't satisfty the io.Writer.

答案1

得分: 1

如果你继续使用指向WriterMock的指针,它应该可以工作:

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

然后:

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

我错过了:

func (this *WriterMock) Write(b []byte) (n int, err error) {
...
}

你需要在指针接收器上调用Write(),而不是值接收器。由于在Go中一切都是按值传递的,使用值接收器会创建WriterMock实例的副本。

英文:

If you keep using a pointer to WriterMock, it should work:

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

Then:

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

I missed:

func (this *WriterMock) Write(b []byte) (n int, err error) {
...
}

You need to call Write() on a pointer receiver, not a value receiver.
Since everything is passed by value in Go, using a value receiver would make a copy of the WriterMock instance.

huangapple
  • 本文由 发表于 2015年3月9日 00:27:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/28928870.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定