如何为返回 ok、err 的函数编写破碎的单元测试?

我有一个 Lua 函数,它返回 false,后跟错误消息,并希望使用busted测试框架测试其行为。现在我正在这样做:

function safe_divide(a, b)
    if b > 0 then -- 有缺陷!应该是 b ~= 0
        return a / b
    else
        return false, "division by zero"
    end
end

describe("safe_divide", function()
    it("可以用正数除法", function()
        local ok, err = safe_divide(10.0, 5.0)
        assert.truthy(ok)
        assert.are.same(2.0, ok)
    end)

    it("除零错误时提示错误", function()
        local ok, err = safe_divide(10.0, 0.0)
        assert.not_truthy(ok)
        assert.are.same("division by zero", err)
    end)

    it("可以分负数", function()
        local ok, err = safe_divide(-10.0, -5.0)
        assert.truthy(ok)
        assert.are.same(2.0, ok)
    end)
end)

我对当前方法不喜欢的有两件事:

  • 每个测试都有 3 行代码,不太简洁。
  • 当第 3 项测试失败时,破碎只说 false 不是预期的 truthy 值,并且从来不提到“除零”错误消息。

我是否可以改进我的测试文件以避免这些问题?

我想我想做的与破碎中的 has_error 断言有些相似,但似乎只适用于实际引发异常的函数,而不适用于返回“false”后跟错误消息的函数。

点赞
用户162054
用户162054

Busted 使用luassert,该模块可以使用自定义断言进行扩展。

例如,以下代码使用一个名为answers的用户定义断言作为第一个参数是预期结果的表格,其余参数为实际函数结果。

local assert = require "luassert"

local function safe_divide(a, b)
    if b > 0 then -- 有缺陷! 应该是 b ~= 0
        return a / b
    else
        return false, "division by zero"
    end
end

local function answers(state, arguments)
  local expected = arguments[1]
  assert(type(expected) == "table")
  for i = 2, #arguments do
      if arguments[i] ~= expected[i-1] then
          state.failure_message = "unexpected result " .. tostring (i-1) .. ": " .. tostring (arguments [i])
          return false
      end
  end
  return true
end
assert:register("assertion", "answers", answers)

describe("safe_divide", function()
    it("can divide by positive numbers", function()
        assert.answers({ 2.0 }, safe_divide(10.0, 5.0))
    end)

    it("errors when dividing by zero", function()
        assert.answers({ false, "division by zero" }, safe_divide(10.0, 0.0))
    end)

    it("can divide by negative numbers", function()
        assert.answers({ 2.0 }, safe_divide(-10.0, -5.0))
    end)
end)

该代码缺少断言消息的正确格式。您可以查看 luaassert 文档,或者查看预定义断言。它包含一个 say 模块用于翻译消息。

2017-09-22 06:52:46