Использование базового десятичного типа в XCTAssertEqual - PullRequest
0 голосов
/ 14 марта 2020

Я строю некоторые классы и код, которые хранят и выполняют арифметику c для значений валют. Первоначально я использовал Doubles, но преобразовал в десятичную из-за арифметических ошибок c.

Я пытаюсь найти лучший способ запуска модульных тестов для функций, работающих с типом Decimal.

Предположим, что position.totalCost - это десятичный тип.

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

Этот код не компилируется, так как десятичное число не соответствует FloatingPoint. XCTAssertEqual требует, чтобы параметры были Doubles или Float.

Я справился с этим, выполнив следующее:

XCTAssertTrue(position.totalCost == 3571.6)

, который работает, но если ошибка возникает во время модульный тест, я получаю смутное сообщение:

XCTAssertTrue failed, а не более полезный XCTAssertEqual failed: ("2.0") is not equal to ("1.0")

Так что использование XCTAssertEqual идеально.

Потенциальные параметры ( как новичок, без понятия, что лучше или жизнеспособнее)

  1. Код мой класс Position для сохранения всех свойств в виде десятичного числа, но использование вычисленных свойств для получения и установки их как двойников.

  2. Написать пользовательское утверждение, которое принимает десятичные дроби. Вероятно, это наиболее «правильный» путь, потому что единственная проблема, с которой я столкнулся при использовании десятичных чисел, заключается в том, что утверждения XCT не могут их принять.

  3. Напишите глупое расширение десятичного числа, которое будет возвращать Двойное значение. По какой-то причине в классе Decimal нет свойства или функции, которая возвращает Double или Floag.

Ответы [ 2 ]

0 голосов
/ 14 марта 2020

Вам действительно нужно указать accuracy из 0.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)  
0 голосов
/ 14 марта 2020

Не переводите 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)
...