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.

The non generic BeEquivalentTo throws a NullReferenceException

See original GitHub issue

Description

When using BeEquivalentTo on an implementation of System.Data.IDataParameterCollection (a non generic collection) containing a list of System.Data.SqlClient.SqlParameter a null reference exception is thrown

Complete minimal example reproducing the issue

//ARRANGE
var expected = new DataParameterCollection
{
	new SqlParameter{ParameterName = "Id", DbType = DbType.Int32, Value = 1},
};


//ACT
var subjectUnderTest = new DataParameterCollection
{
	new SqlParameter{ParameterName = "Id", DbType = DbType.Int32, Value = 1},
};

//ASSERT
subjectUnderTest.Should().BeEquivalentTo(expected);

Expected behavior:

The assertion should be true.

Actual behavior:

System.NullReferenceException: Object reference not set to an instance of an object. at System.Data.SqlClient.SqlParameter.get_IsNull()

Versions

.NET Core 2.1

Additional Information

class DataParameterCollection : IDataParameterCollection
{
	private readonly IList _list;

	public DataParameterCollection()
	{
		_list = new List<IDbDataParameter>(); // ArrayList or List<object> gives the same exception
	}
        // Adding this property and using it for the assertion instead solves the issue
	public IList<IDbDataParameter> InternalList => _list as IList<IDbDataParameter>;

	/// <inheritdoc />
	public IEnumerator GetEnumerator() => _list.GetEnumerator();

	/// <inheritdoc />
	public void CopyTo(Array array, int index) => _list.CopyTo(array, index);

	/// <inheritdoc />
	public int Count => _list.Count;

	/// <inheritdoc />
	public bool IsSynchronized => _list.IsSynchronized;

	public object SyncRoot => _list.SyncRoot;

	/// <inheritdoc />
	public int Add(object value) => _list.Add(value);

	/// <inheritdoc />
	public void Clear() => _list.Clear();


	/// <inheritdoc />
	public bool Contains(object value) => _list.Contains(value);

	/// <inheritdoc />
	public int IndexOf(object value) => _list.IndexOf(value);

	/// <inheritdoc />
	public void Insert(int index, object value) => _list.Insert(index, value);

	/// <inheritdoc />
	public void Remove(object value) => _list.Remove(value);

	/// <inheritdoc />
	public void RemoveAt(int index) => _list.RemoveAt(index);

	/// <inheritdoc />
	public bool IsFixedSize => _list.IsFixedSize;

	/// <inheritdoc />
	public bool IsReadOnly => _list.IsReadOnly;

	/// <inheritdoc />
	public object this[int index]
	{
		get => _list[index];
		set => _list[index] = value;
	}

	/// <inheritdoc />
	public bool Contains(string parameterName) => _list.Cast<IDbDataParameter>().SingleOrDefault(p => p.ParameterName.Equals(parameterName)) != null;

	/// <inheritdoc />
	public int IndexOf(string parameterName) =>
		_list.IndexOf(_list.Cast<IDbDataParameter>().SingleOrDefault(p => p.ParameterName.Equals(parameterName)));

	/// <inheritdoc />
	public void RemoveAt(string parameterName) => _list.RemoveAt(IndexOf(parameterName));

	/// <inheritdoc />
	public object this[string parameterName]
	{
		get => _list.Cast<IDbDataParameter>().SingleOrDefault(p => p.ParameterName.Equals(parameterName));
		set => throw new NotImplementedException();
	}
}

Exception message

   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, Object[] index)
   at FluentAssertions.Equivalency.EquivalencyValidationContextExtentions.CreateForNestedMember(IEquivalencyValidationContext context, SelectedMemberInfo nestedMember, SelectedMemberInfo matchingProperty) in C:\projects\fluentassertions-vf06b\Src\FluentAssertions\Equivalency\EquivalencyValidationContextExtentions.cs:line 14
   at FluentAssertions.Equivalency.StructuralEqualityEquivalencyStep.Handle(IEquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config) in C:\projects\fluentassertions-vf06b\Src\FluentAssertions\Equivalency\StructuralEqualityEquivalencyStep.cs:line 46
   at FluentAssertions.Equivalency.EquivalencyValidator.AssertEqualityUsing(IEquivalencyValidationContext context) in C:\projects\fluentassertions-vf06b\Src\FluentAssertions\Equivalency\EquivalencyValidator.cs:line 85
   at FluentAssertions.Equivalency.EnumerableEquivalencyValidator.TryToMatch[T](Object subject, T expectation, Int32 expectationIndex) in C:\projects\fluentassertions-vf06b\Src\FluentAssertions\Equivalency\EnumerableEquivalencyValidator.cs:line 132
   at FluentAssertions.Equivalency.EnumerableEquivalencyValidator.LooselyMatchAgainst[T](IList`1 subjects, T expectation, Int32 expectationIndex) in C:\projects\fluentassertions-vf06b\Src\FluentAssertions\Equivalency\EnumerableEquivalencyValidator.cs:line 103
   at FluentAssertions.Equivalency.EnumerableEquivalencyValidator.AssertElementGraphEquivalency[T](Object[] subjects, T[] expectations) in C:\projects\fluentassertions-vf06b\Src\FluentAssertions\Equivalency\EnumerableEquivalencyValidator.cs:line 73
   at FluentAssertions.Equivalency.EnumerableEquivalencyValidator.Execute[T](Object[] subject, T[] expectation) in C:\projects\fluentassertions-vf06b\Src\FluentAssertions\Equivalency\EnumerableEquivalencyValidator.cs:line 40
   at FluentAssertions.Equivalency.EnumerableEquivalencyStep.Handle(IEquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config) in C:\projects\fluentassertions-vf06b\Src\FluentAssertions\Equivalency\EnumerableEquivalencyStep.cs:line 45
   at FluentAssertions.Equivalency.EquivalencyValidator.AssertEqualityUsing(IEquivalencyValidationContext context) in C:\projects\fluentassertions-vf06b\Src\FluentAssertions\Equivalency\EquivalencyValidator.cs:line 85
   at FluentAssertions.Equivalency.EquivalencyValidator.AssertEquality(EquivalencyValidationContext context) in C:\projects\fluentassertions-vf06b\Src\FluentAssertions\Equivalency\EquivalencyValidator.cs:line 38
   at FluentAssertions.Collections.NonGenericCollectionAssertions.BeEquivalentTo(IEnumerable expectation, String because, Object[] becauseArgs) in C:\projects\fluentassertions-vf06b\Src\FluentAssertions\Collections\NonGenericCollectionAssertions.cs:line 326
   at Anon.ClassName.BeEquivalantTo_NonGenericList_ShouldNotThrow() in C:\Code\Fluent\src\Project\ClassName.cs:line 10

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:9 (7 by maintainers)

github_iconTop GitHub Comments

2reactions
jnyrupcommented, Jul 24, 2018

@Toudahl A much prettier approach for you would be to combine Including()/Excluding() and WhichGetterHas()/WhichGetterDoesNotHave().

subjectUnderTest.Should().BeEquivalentTo(expected,
    opt => opt.Excluding(ctx => ctx.WhichGetterHas(CSharpAccessModifier.Internal)));

subjectUnderTest.Should().BeEquivalentTo(expected,
    opt => opt.Excluding(ctx => ctx.WhichGetterDoesNotHave(CSharpAccessModifier.Public)));

subjectUnderTest.Should().BeEquivalentTo(expected, 
    opt => opt.Including(ctx => ctx.WhichGetterHas(CSharpAccessModifier.Public)));

subjectUnderTest.Should().BeEquivalentTo(expected, 
    opt => opt.Including(ctx => ctx.WhichGetterDoesNotHave(CSharpAccessModifier.Internal)));
0reactions
Toudahlcommented, Jul 25, 2018

I must have made a mistake when i tried it earlier today. It does indeed work as you say.

Read more comments on GitHub >

github_iconTop Results From Across the Web

c# - What is a NullReferenceException, and how do I fix it?
This means the reference is null , and you cannot access members (such as methods) through a null reference. The simplest case: string...
Read more >
Upgrading to version 6.0 - Fluent Assertions
Case (3) works as expected, as List<T> is not implicitly convertible to T[] and the compiler picks BeEquivalentTo(IEnumerable<I>) , which retains the compile ......
Read more >
9 Fluent Assertions Tricks to Save Hours of Your Testing ...
BeEquivalentTo method compares properties and it requires that properties have the same names, no matter the actual type of the properties. Fluent Assertions ......
Read more >
Tips - Fluent Assertions
Expected string not to be <null> or whitespace, but found " ". Assertion, Improvement. actual.Length.
Read more >
How can I fix the error: System.NullReferenceException
A NullReferenceException exception is thrown when you try to access a member on a type whose value is null. A NullReferenceException exception ...
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