在XCTAssertEqual中使用基础十进制类型

问题描述 投票:0回答:2

我正在构建一些类和代码来存储货币值并对其进行算术运算。我最初使用Doubles,但由于算术错误而转换为Decimal。

我正在尝试找到针对使用Decimal类型的函数运行单元测试的最佳方法。

考虑position.totalCost是一个十进制类型。

XCTAssertEqual(position.totalCost, 3571.6, accuracy: 0.01)

此代码无法编译,因为Decimal不符合FloatingPoint。 XCTAssertEqual要求参数为Doubles或Floats。

我通过以下操作解决了这个问题:

XCTAssertTrue(position.totalCost == 3571.6)

这确实有效,但是如果在单元测试期间出现错误,我会得到模糊的消息:

XCTAssertTrue failed而不是更有用的XCTAssertEqual failed: ("2.0") is not equal to ("1.0")

所以使用XCTAssertEqual是理想的。

潜在选项(作为新手,没有更好或更可行的线索)

  1. 编码我的Position类以将所有属性存储为Decimal,但使用计算出的属性来获取它们并将其设置为Doubles。

  2. 编写一个接受小数的自定义断言。这可能是最“正确”的路径,因为到目前为止,我使用Decimals遇到的唯一问题是XCT断言无法接受它们。

  3. 写一个愚蠢的十进制扩展名,它将返回一个Double值。无论出于何种原因,Decimal类中都没有返回Double或Floag的属性或函数。

swift xctest foundation
2个回答
0
投票

如果不需要,请不要将Decimal转换为浮点,因为这会导致精度损失。如果要比较两个Decimal值的准确性,可以使用Decimal.distance(to:)函数,如下所示:

let other = Decimal(35716) / Decimal(10) // 3571.6
let absoluteDistance = abs(position.totalCost.distance(to: other))
let accuracy = Decimal(1) / Decimal(100) // 0.01
XCTAssertTrue(absoluteDistance < accuracy)

-1
投票

您真的需要指定accuracy0.01吗?

由于省略了该参数,所以编译就很好。

struct Position {
    let totalCost: Decimal
}

let position = Position(totalCost: 3571.6)

//passes
XCTAssertEqual(position.totalCost, 3571.6)  

// XCTAssertEqual failed: ("3571.6") is not equal to ("3571.61")
XCTAssertEqual(position.totalCost, 3571.61)  
© www.soinside.com 2019 - 2024. All rights reserved.