7

EDIT: There is a similar question here, but the solutions only suggest workarounds and provide no insights into the cause of the issue or how to fix it. This question may still be a duplicate.

EDIT 2: It turns out this issue is only happening during debug, although it was not happening earlier. After replacing (TCheck)null with null as TCheck the tests pass when ran but throw an exception when debugged.

ORIGINAL POST: I have a method in a unit test that looks like this

internal void EqualityAssert<TCheck, TEquatable>(TEquatable item, ... ) 
    where TCheck : class, IEquatable<TEquatable>, TEquatable
{

    // Various equality assertions that are passing
    // ...

    // A == null       
    Assert.Throws<NullReferenceException>(
    () => ((IEquatable<TEquatable>)item).Equals((TCheck)null));            
}

This method is called by various unit tests, and each of those tests are failing because an "Unhandled NullReferenceException was encountered" exactly where it is expected.

Assert.Throws was working properly for me earlier but I haven't been able to figure out what changed to break it.

Community
  • 1
  • 1
Kelson Ball
  • 948
  • 1
  • 13
  • 30
  • Could be because of the `(TCheck)null`. Try changing this to `null as TCheck`. I've just given this a go and it doesn't look likely but it'd be nice to see what happens in your scenario. – Stephen Ross Mar 22 '16 at 17:47
  • Have you tried debugging your test? – rclocher3 Mar 22 '16 at 17:50
  • @StephenRoss That did not resolve the issue, I still get the exception in the Equals implementation, exactly where it was expected. – Kelson Ball Mar 22 '16 at 17:50
  • @rclocher3 Perhaps I misunderstand your question..yes I am stepping through the test and inspecting values and everything is as expected. Is there a more specific debugging approach you are asking about? – Kelson Ball Mar 22 '16 at 17:52
  • No, I was just remembering a time when my test was failing because of an uncaught exception that I thought was expected, but it turned out that an exception was being thrown elsewhere in the code. Good luck to you. – rclocher3 Mar 22 '16 at 17:56
  • Does assigning the value of `((IEquatable)item).Equals((TCheck)null)` to a temp prevent it from being optimized out by the JITter? In your playing about, are you ending up calling `Object.Equals(Object)` instead of the `IEquatable` one? Make sure you're showing us your actual code as much as possible... – Ruben Bartelink Mar 22 '16 at 19:42
  • I have had a lot of issues with Object.Equals being called rather than IEquatable.Equals up until this point - hence the explicit cast of item to IEquatable. The exception is being thrown in the method that implements IEquatable, so I am 100% sure that is the method that is being called now. If before the changes Object.Equals was being called that might be what lead to the issue seemingly appearing out of nowhere. – Kelson Ball Mar 22 '16 at 20:30

2 Answers2

6

Better to use this pattern:

[Fact]
public void Divide_TwoNumbers_ExpectException()
{
    var sut = new Calculator();
    var exception = Record.Exception(() => sut.Divide(10, 0));
    Assert.IsType(typeof(DivideByZeroException), exception);
}
Rosdi Kasim
  • 24,267
  • 23
  • 130
  • 154
user1829319
  • 691
  • 1
  • 8
  • 22
0

You throw exception but you should handle it.Check below code. You can modify your code according to my example.

var message = FakeRequestBuilder.CreateSettlementFileMessage();

var warning = Assert.Throws<ExF.Core.Exception.IntegrationValidationException>(
                () => createSettlementFileHandler.Handle(message));

Assert.Equal(warning.ErrorCode, -1);
LeftyX
  • 35,328
  • 21
  • 132
  • 193