【问题标题】:Is it possible to dynamically assert if two values are equal or not equal when unit testing in Go?在 Go 中进行单元测试时,是否可以动态断言两个值是否相等?
【发布时间】:2017-10-09 09:29:42
【问题描述】:

我刚刚开始使用 Go。我正在编写单元测试,我希望能够使用表格进行测试,其中要与实际结果进行比较的结果有时应该或不应该相等。

例如,这是我目前拥有的代码:

package main

import (
    "github.com/stretchr/testify/assert"
    "testing"
)

func TestFunc(t *testing.T) {
    tables := []struct {
        input               string
        comparisonResult    string
        shouldBeEqual       bool
    }{
        {
            "some irrelevant input",
            "some result",
            true,
        },
        {
            "some other irrelevant input",
            "some other result",
            false,
        },
    }

    for _, table := range tables {
        actualResult := sampleFunc(table.input)
        if table.shouldBeEqual {
            assert.Equal(t, table.expectedResult, actualResult)
        } else {
            assert.NotEqual(t, table.expectedResult, actualResult)
        }
    }
}

现在,这还不算太糟糕,但如果可以将最后一位更改为更清晰的内容以提高可读性,那就更好了:

for _, table := range tables {
    actualResult := sampleFunc(table.input)
    assert.EqualOrNotEqual(t, table.comparisonResult, actualResult, table.shouldBeEqual)
}

因此,如果table.comparisonResultactualResult 相等,则第一个测试应该通过,如果两个 相等,则第二个测试应该通过。

我查看了testify/assert docs,我认为我没有找到类似于我上面编造的假EqualOrNotEqual 函数的函数,但也许我不小心跳过了某些东西,或者有一些一种我不知道的 Go 特殊语法可能会帮助我实现这一目标。

注意:我很清楚我可以为此编写自己的函数。我问的原因是因为如果这是一个成熟的模式,那么包/库通常将它作为内置函数包含在文档中,有时可能没有记录/埋在文档中。如果没有,也许我不应该这样做是有原因的,或者也许有更好的方法。开始使用一门新语言一开始是非常费力的,尤其是因为你必须学习所有新的习语和怪癖以及做事的正确方法。

【问题讨论】:

  • 您不需要特殊语法或任何库提供的函数。你说的是五行代码——为什么不自己写函数呢?
  • 我同意。我想要它,我不需要它。创建我自己的函数非常简单,但如果经常出现这种情况,包通常会包含这类东西。既然好像没有被包含,那我就直接写函数了。问一问总无妨。 :)

标签: unit-testing testing go testify


【解决方案1】:

由于它只是为了便于阅读,并且由于该函数似乎不存在,您可以将工作代码复制粘贴到单独的函数中:

func equalOrNotEqual(t TestingT, expected, actual interface{}, shouldBeEqual bool) {
    if shouldBeEqual {
        assert.Equal(t, expected, actual)
    } else {
        assert.NotEqual(t, expected, actual)
    }
}

和:

for _, table := range tables {
    actualResult := sampleFunc(table.input)
    equalOrNotEqual(t, table.comparisonResult, actualResult, table.shouldBeEqual)
}

【讨论】:

    【解决方案2】:

    Golang 确实有一个功能方面,尽管它比 Python 或 JavaScript 更严格。

    如果您知道函数的签名,您可以允许您的结构表保存函数。然后你摆脱了测试中的if 逻辑:

    func TestFunc(t *testing.T) {
        tables := []struct {
            input            string
            comparisonResult string
            assert           func(assert.TestingT, interface{}, interface{}, ...interface{}) bool
        }{
            {
                input:            "some irrelevant input",
                comparisonResult: "some result",
                assert:           assert.Equal,
            },
            {
                input:            "some other irrelevant input",
                comparisonResult: "some other result",
                assert:           assert.NotEqual,
            },
        }
    
        for _, table := range tables {
            actualResult := sampleFunc(table.input)
            table.assert(t, table.comparisonResult, actualResult)
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-14
      • 2013-03-18
      • 1970-01-01
      • 2015-05-04
      • 2014-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多