英文:
Go assert.Equal some interface with time.Time object inside
问题
我正在尝试检查返回的数据是否与期望值相等。
这是我的函数:
func extractData(payload string) (interface{}, time.Time, error) {
eventTime := gjson.Get(payload, "data.eventDateTime").String()
dateTime, err := time.Parse("2006-01-02T15:04:05-07:00", eventTime)
if err != nil {
return nil, time.Time{}, fmt.Errorf("日期时间错误:%w", err)
}
body := data.Body{
EventTime: dateTime,
}
return body, dateTime, nil
}
这是我为它编写的单元测试:
func TestExtractData(t *testing.T) {
tests := []struct {
Name string
Payload string
ExpectedOutput interface{}
}{
{
Name: "test-2",
Payload: `{"data":"2020-11-02T10:44:48+01:00"}`,
ExpectedOutput: data.Body{
EventTime: time.Date(2020, 11, 2, 10, 44, 48, 0, time.FixedZone("CET", 3600)),
},
},
}
for _, tt := range tests {
t.Run(tt.Name, func(t *testing.T) {
data, _, _ := extractData(tt.Payload)
assert.Equal(t, tt.ExpectedOutput, data)
})
}
}
测试失败,输出如下:
{ 2020-11-02 10:44:48 +0100 CET} 不等于 { 2020-11-02 10:44:48 +0100 CET}
我认为问题在于TimeZone
,但我在编写测试代码时遇到了困难。
我不想使用time.Equal
进行测试,因为我的data.Body
并不总是包含eventTime
元素。
我尝试了以下方法(通过临时使用非接口类型):
if !tt.ExpectedOutput.EventTime.Equal(data.EventTime) {
// 抛出错误
}
它可以工作。
我还尝试了:
if !reflect.DeepEqual(tt.ExpectedOutput.EventTime, data.EventTime) {
t.Errorf("extractData() 输出 = %v,期望值 = %v", data, tt.ExpectedOutput)
}
上面的代码失败了。
英文:
I am trying to check if the returned data equals the expectation
Here is my function:
func extractData(payload string) (interface{}, time.Time, error) {
eventTime := gjson.Get(payload, "data.eventDateTime").String()
dateTime, err := time.Parse("2006-01-02T15:04:05-07:00", eventTime)
if err != nil {
return nil, time.Time{}, fmt.Errorf("Date Time Error: %w", err)
}
body := data.Body{
EventTime: dateTime,
}
return body, dateTime, nil
}
This is the unit test I wrote for it:
func TestExtractData(t *testing.T) {
tests := []struct {
Name string
Payload string
ExpectedOutput interface{}
}{
{
Name: "test-2",
Payload: "{\"data\":\"2020-11-02T10:44:48+01:00\"}",
ExpectedOutput: data.Body{
EventTime: time.Date(2020, 11, 2, 10, 44, 48, 0, time.FixedZone("CET", 3600)),
},
},
}
for _, tt := range tests {
t.Run(tt.Name, func(t *testing.T) {
data, _, _ := extractData(tt.Payload)
assert.Equal(t, tt.ExpectedOutput, data)
})
}
}
The test is failing, it outputs:
{ 2020-11-02 10:44:48 +0100 CET} does not equal { 2020-11-02 10:44:48 +0100 CET}
I believe the problem is in TimeZone
, but I struggles to write the test code.
I don't want to test it using time.Equal
, because my data.Body
does not always contains the eventTime
element.
I tried (by temporary use type not interface):
if !tt.ExpectedOutput.EventTime.Equal(data.EventTime) {
//throw error
}
and it works.
I also i tried:
if !reflect.DeepEqual(tt.ExpectedOutput.EventTime, data.EventTime) {
t.Errorf("extractData() output = %v, want = %v",data,tt.ExpectedOutput)
}
The code above fails.
答案1
得分: 5
你部分正确,时区可能导致表示相同时间的两个time.Time
实例无法相等。另外,自Go 1.9以来,time.Time
还包括了墙上时间,以确保所有比较都是安全的,因此time.Time
字面量(例如你的ExpectedOutput
字段)将不包含这个墙上时间,所以它们是“不同的”。
你最好的解决方案可能是使用assert.WithinDuration()
来比较时间(我假设你正在使用github.com/stretchr/testify/assert
):
package kata
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestTime(t *testing.T) {
format := "2006-01-02 15:04:05.999999999 -0700 MST"
time1 := time.Now()
time2, err := time.Parse(format, time1.Format(format))
assert.NoError(t, err)
t.Log(time1)
t.Log(time2)
assert.Equal(t, time1, time2) // 失败
assert.WithinDuration(t, time1, time2, 0) // 通过
}
英文:
You're partially correct that the time zone can make two time.Time
instances representing the same time fail equality. It can also be that because since go 1.9, time.Time
also includes wall time to make all comparisons safe, time.Time
literals such as your ExpectedOutput
field will never contain this wall time, so are "different".
Your best solution is probably to compare the time using assert.WithinDuration()
(I assume you are using github.com/stretchr/testify/assert
?):
package kata
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestTime(t *testing.T) {
format := "2006-01-02 15:04:05.999999999 -0700 MST"
time1 := time.Now()
time2, err := time.Parse(format, time1.Format(format))
assert.NoError(t, err)
t.Log(time1)
t.Log(time2)
assert.Equal(t, time1, time2) // fails
assert.WithinDuration(t, time1, time2, 0) // passes
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论