php - 使用 Laravel assertDatabaseHas 和浮点列进行单元测试
问题描述
在我的 Laravel 应用程序上进行一些测试,由于我的数据库列之一被定义为FLOAT
. 使用assertDatabaseHas()
它运行测试时,有时会由于浮点不确定性而失败。
<?php
namespace Test\Unit;
use App\Foo;
class MyModelTest extends TestCase
{
public function testFooCanBar(): void
{
$stringvalue = "baz";
$floatvalue = 234.281;
$data = [
"name" => $stringvalue,
"data" => $floatvalue,
];
Foo::bar($stringvalue, $floatvalue);
$this->assertDatabaseHas("foos", $data);
}
}
有时结果:
Failed asserting that a row in the table [foos] matches the attributes {
"name": "baz",
"data": 234.281
}.
Found similar results: [
{
"name": "baz",
"data": 234.280999999999999995
}
]
我可以想出几种方法来解决这个问题(将列更改为 anINT
并乘以 10^x,或者只是从比较中删除列)但我想知道是否有任何方法我错过了正确检查这个。当直接比较值时,我们可以使用 PHPUnit 的assertEqualsWithDelta()
; 数据库检查有什么类似的吗?
解决方案
在 MySQL 数据库(当前为 v8)中,aFLOAT
或DOUBLE
数据类型始终存储为近似值:
FLOAT 和 DOUBLE 类型表示近似数值数据值。MySQL 对单精度值使用四个字节,对双精度值使用八个字节。
另一方面,DECIMAL
数据类型允许您存储长达 65 位的精确十进制值。
DECIMAL 和 NUMERIC 类型存储精确的数字数据值。当保持精确的精度很重要时使用这些类型,例如货币数据。
— 来自:MySQL DECIMAL 数据类型参考
FLOAT 的问题(参考)
MySQL 文档涵盖了数据类型不准确的问题,并显示了在数据库级别使用这些类型和差异差异的可能解决方案(参考链接中的完整示例)FLOAT
:DOUBLE
SELECT i, SUM(d1) AS a, SUM(d2) AS b
FROM t1
GROUP BY i
HAVING ABS(a - b) > 0.0001;
重要提示:请记住,这FLOAT
也是DOUBLE
平台相关的!
SELECT
像下面这样的语句可以根据运行时环境返回0
and-0
或inf
and :-inf
CREATE TABLE t1(c1 FLOAT(53,0), c2 FLOAT(53,0));
INSERT INTO t1 VALUES('1e+52','-1e+52');
SELECT * FROM t1;
推荐阅读
- php - Use define as you get function data return
- python - Flask SQLAlchemy - Default filter value if no results for provided filter
- cinema-4d - 在 Cinema 4D 中水平拉伸纹理
- microsoft-teams - Microsoft Teams:需要在自定义选项卡中为 Sharepoint 文档提供“在 Teams 中编辑”
- java - Quartz 作业正在运行 - 无法连接到 SFTP 服务器 - 连接重置
- python - 以“__”开头但强制执行 PascalCase 的属性名称规则
- javascript - 如何从js中的字符串构建变量?
- angularjs - CKeditor 4.13.0 在 AngularJS 中提到插件:不要在下拉列表中显示 @
- go - Bufio Scanner Goroutine - truncated/unordered output
- math - Highly independent means highly not co-related?