如何在Go单元测试中比较值

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

How to compare values in a Go unit test

问题

我有一个方法,对于某些输入返回一个带有状态码的错误。我想在单元测试中检查它:

_, err := x.MyMethod(....)
if err == nil {
    t.Error("Expected error")
}
e, ok := status.FromError(err)
assert.Equal(e.Code(), codes.ResourceExhausted, "....")

但是我看到一个编译错误:

无法将 e.Code()(类型为 codes.Code 的值)作为 assert.TestingT 的参数传递给 assert.Equal:codes.Code 没有实现 assert.TestingT(缺少 Errorf 方法)

为什么我不能比较这两个值?错误消息似乎意味着我需要比较的每种类型都必须实现 assert.TestingT。e.Code() 简单地返回标准 Go 库中的 codes.Code,它是一个 uint32 类型。

英文:

I have a method that returns an error with status code for some inputs. I want to check for it in unit test:

_, err := x.MyMethod(....)
if err == nil {
    t.Error("Expected error")
}
e, ok := status.FromError(err)
assert.Equal(e.Code(), codes.ResourceExhausted, "....")

But I see a compilation error:

> cannot use e.Code() (value of type codes.Code) as assert.TestingT
> value in argument to assert.Equal: codes.Code does not implement
> assert.TestingT (missing method Errorf)

Why can’t I compare two values? The error message seems to mean every type I need to compare must implement assert.TestingT.
e.Code() simply returns codes.Code from the standard Go library, and it’s an uint32.

答案1

得分: 2

编译错误是因为assert.Equal函数期望其第一个参数实现TestingT接口,该接口提供了用于报告测试失败的Errorf方法。然而,gRPC包中的codes.Code并没有实现这个接口,因此会出现错误。

要解决这个问题,你可以使用assert.EqualValues代替assert.Equal。assert.EqualValues函数对值进行深度比较,而不需要第一个参数实现TestingT接口。

下面是你可以修改单元测试的方式:

func TestMyMethod(t *testing.T) {
    // 假设x是包含MyMethod的结构体的实例

    // ... 设置测试输入的代码 ...

    _, err := x.MyMethod(....)
    if err == nil {
        t.Error("期望出现错误")
    }

    e, ok := status.FromError(err)
    if !ok {
        t.Errorf("期望出现gRPC状态错误")
    }

    assert.EqualValues(e.Code(), codes.ResourceExhausted, "期望出现ResourceExhausted错误码")
}

通过使用assert.EqualValues,测试现在将正确比较codes.Code的值,而不需要它实现TestingT接口。确保导入了github.com/stretchr/testify/assert包,以便断言函数正常工作。

英文:

The compilation error is occurring because the assert.Equal function expects its first argument to implement the TestingT interface, which provides the Errorf method used to report test failures. However, codes.Code from the gRPC package does not implement this interface, hence the error.

To resolve this, you can use assert.EqualValues instead of assert.Equal. The assert.EqualValues function performs a deep comparison of the values without requiring the first argument to implement the TestingT interface.

Here's how you can modify your unit test:

    func TestMyMethod(t *testing.T) {
    // Assuming x is an instance of the struct containing MyMethod

    // ... code to set up test inputs ...

    _, err := x.MyMethod(....)
    if err == nil {
        t.Error("Expected error")
    }

    e, ok := status.FromError(err)
    if !ok {
        t.Errorf("Expected gRPC status error")
    }

    assert.EqualValues(e.Code(), codes.ResourceExhausted, "Expected ResourceExhausted error code")
}

By using assert.EqualValues, the test will now correctly compare the codes.Code value without requiring it to implement the TestingT interface. Make sure you have the github.com/stretchr/testify/assert package imported for the assertion functions to work.

答案2

得分: -1

require包可以解决编译错误。

import (
    "testing"
    "github.com/stretchr/testify/require"
    
    ...

)

func TestMyMethod(t *testing.T) {
    _, err := x.MyMethod(....)

    if err == nil {
        t.Error("预期错误")
    }

    e, ok := status.FromError(err)

    require.Equal(t, codes.ResourceExhausted, e.Code(), "预期 ResourceExhausted 错误代码")
}
英文:

package require could solve the compilation error.

import (
    "testing"
    "github.com/stretchr/testify/require"
    
    ...

)

func TestMyMethod(t *testing.T) {
    _, err := x.MyMethod(....)

    if err == nil {
        t.Error("Expected error")
    }

    e, ok := status.FromError(err)

    require.Equal(t, codes.ResourceExhausted, e.Code(), "Expected ResourceExhausted error code")
}

huangapple
  • 本文由 发表于 2023年7月26日 18:03:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/76770098.html
匿名

发表评论

匿名网友

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

确定