question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Comparing datatables with dbnull in expectation doesn't cause test to fail when subject has a value

See original GitHub issue

Description

Comparing DataTables where a column in the expectation containing a dbnull value passes comparison regardless of the value in the same column in the subject.

Complete minimal example reproducing the issue

// Arrange
var expected = new DataTable();
expected.Columns.AddRange(new[] 
{ 
    new DataColumn("Column1", typeof(string)), 
    new DataColumn("Column2", typeof(string)), 
    new DataColumn("Column3", typeof(string)) 
});

expected.Rows.Add("test", null, "1" );

// Act
var actual = new DataTable();
actual.Columns.AddRange(new[] 
{
    new DataColumn("Column1", typeof(string)),
    new DataColumn("Column2", typeof(string)),
    new DataColumn("Column3", typeof(string))
});
actual.Rows.Add("test", "fail", "1");

// Assert
actual.Should().BeEquivalentTo(expected);

Expected behavior:

The test to fail because “Column2” in the expectation is null while it has a value of “fail” in the subject

Actual behavior:

The test passes. Reversing the order leads to the test failing as expected, i.e.,

// Assert
expected.Should().BeEquivalentTo(actual);

fails.

Versions

  • Which version of Fluent Assertions are you using? 6.7.0
  • Which .NET runtime and version are you targeting? .NET 6

Additional Information

Any additional information, configuration or data that might be necessary to reproduce the issue.

Issue Analytics

  • State:open
  • Created a year ago
  • Comments:7 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
dennisdoomencommented, Jul 23, 2022

The reason for this is that DbNull.Value is a singleton which does not override Equals. You can call Equals on it, but it will defer to the default object.Equals implementation, which will use reference equality. Since Value always returns the same instance, comparing it to itself will work. Because of this behavior, our HasValueSemantics extension method will not treat it as a value type and thus tell BeEquivalentTo to treat it as a complex type. But since the DbNull instance doesn’t have properties or fields, nothing will happen.

You can work around this by using the ComparingByValue<DBNull>() option, but the default formatter won’t make the message very nice:

Expected property actual.Value to be , but found "fail".

So maybe we should treat DbNull as something special?

0reactions
Cornielcommented, Jun 8, 2023

Although I personally hardly use DbNull.Value at all (anymore), I think the types deserves a special treatment. You could even argue that objects (including new object()) that do not have properties should always be treated as value types.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Comparing Data Tables with DBNULL values - vb.net
It is throwing the exception when comparing the COLUMN_DEFAULT column from INFORMATION_SCHEMA.COLUMNS, which has NULL values in it. The way I'm ...
Read more >
Comparing two DataTables with inconsistent values - Studio
I'll be comparing two datatables, the first extracted from an accounting software (ExtractedTable), the second from a CSV file (CSVTable).
Read more >
ApexSQL Data Diff release notes
201564: "Unable to cast object of type 'System.DBNull' to type 'System.String'" message is shown when comparing two databases while one database ...
Read more >
System.Data - Fluent Assertions
BeEquivalentTo(dataRow) : Performs a deep equivalency comparison between the subject and the expectation. This includes comparing field values, for which the ...
Read more >
Microsoft: Please allow Null values to be returned from ...
This error is caused because the constraints of the strongly typed dataset are such that one or more columns contains an invalid value....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found