如何使用FluentAssertions忽略列类型校验两个DataTable的等价性?
DataTable类型不匹配校验问题的解决办法
针对你遇到的expected列类型为double/string、actual列全为object,用AllowingMismatchedTypes()仍提示类型不匹配的问题,给你几个可行的解决思路:
方案一:手动对齐列类型后再校验
框架的类型校验会优先对比DataColumn的DataType属性,而非实际存储值的类型。先把actual的列类型改成和expected一致的,再执行校验:
// 遍历列,将actual的列类型同步为expected的对应类型 for (int i = 0; i < expected.Columns.Count; i++) { var expectedCol = expected.Columns[i]; var actualCol = actual.Columns[i]; // 注意:如果actual列中有无法转换的值,这里会抛出异常,需要提前处理 actualCol.DataType = expectedCol.DataType; } // 之后再用原有的校验逻辑 actual.Should().BeEquivalentTo(expected, options => options.AllowingMismatchedTypes());
方案二:精准排除DataType的校验规则
之前的排除规则无效,大概率是因为没有精准定位到DataColumn的DataType属性。以FluentAssertions为例,调整排除规则的路径:
actual.Should().BeEquivalentTo(expected, options => options.Excluding(ctx => ctx.SelectedMemberInfo?.Name == "DataType" && ctx.Parent?.Type == typeof(DataColumn)) .AllowingMismatchedTypes());
这里明确指定只排除DataColumn对象下的DataType属性,避免误排除其他同名属性。
方案三:直接对比数据内容(绕过列类型校验)
如果只关心数据是否等价,不纠结列的类型定义,可以自己写逻辑遍历行和列,直接对比值(自动处理兼容类型转换):
bool tablesAreEquivalent = true; // 先校验行列数是否一致 if (expected.Rows.Count != actual.Rows.Count || expected.Columns.Count != actual.Columns.Count) { tablesAreEquivalent = false; } else { foreach (DataRow expectedRow in expected.Rows) { var actualRow = actual.Rows[expectedRow.Table.Rows.IndexOf(expectedRow)]; foreach (DataColumn expectedCol in expected.Columns) { var expectedVal = expectedRow[expectedCol]; var actualVal = actualRow[expectedCol.ColumnName]; // 处理空值/DBNull的情况 if ((expectedVal is DBNull || expectedVal == null) && (actualVal is DBNull || actualVal == null)) { continue; } try { // 将actual的值转换为expected列的类型后对比 var convertedActual = Convert.ChangeType(actualVal, expectedCol.DataType); if (!convertedActual.Equals(expectedVal)) { tablesAreEquivalent = false; break; } } catch { // 转换失败,说明值不兼容 tablesAreEquivalent = false; break; } } if (!tablesAreEquivalent) break; } } // 最后判断结果 tablesAreEquivalent.Should().BeTrue();
内容的提问来源于stack exchange,提问作者XtianGIS
相关产品推荐
相关产品推荐

