You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
By checking equality of references, I faced a problem when I used NUnit SameAsConstraint (Is.SameAs(...)) in mocks verification method. The assertion evaluates to false, although both references are equal. By switching from NUnit SameAsConstraint to a direct comparison (e.g.: It.Is(input => input.Equals(sameReferenceAsInput)) performs flawless.
I created a small example to reproduce the issue:
Lets look at a simple class that adds two numbers an emits a proper event when calculation is performed. The sender argument of the event references the event sending instance following .Net framework design guidelines:
public class SomeService
{
public event EventHandler<EventArgs> OnAdd;
public int Add(int left, int right)
{
if (this.OnAdd != null)
{
this.OnAdd(this, new EventArgs());
}
return left + right;
}
}
Then look at both tests doing exactly the same. The only difference is implementation of assertions:
/// <summary>
/// Contains two tests exploring the behaviour od Nuint SameAsConstrain
/// in comparison to dirtly checking for references equality.
/// </summary>
[TestFixture]
public class SomeServiceTest
{
/// <summary>
/// This tests verifies whether the Event OnAdd was triggered
/// when the Add operation of the service is invoked.
/// The failing of the test is incorrect and Is.SameAs
/// (Nunit SameAsConstraint) reports and error, although
/// compared references are equal.
/// </summary>
[Test]
public void FailingTest_DueToWrongEvalutionOfSameAsConstraint()
{
var instanceUnderTest = new SomeService();
var mockHandler = new Mock<IOnAddEventHanlder>();
instanceUnderTest.OnAdd += mockHandler.Object.HandleOnAdd;
instanceUnderTest.Add(1, 2);
mockHandler.Verify(m => m.HandleOnAdd(
Is.SameAs(instanceUnderTest),
It.IsAny<EventArgs>()));
}
/// <summary>
/// This tests verifies whether the Evnet OnAdd was triggered
/// when the Add operation of the service is invoked.
/// This test executes as expected. The compared references are
/// equal and consequently our assertion does not fail.
/// </summary>
[Test]
public void SucceedingTest_DueToExecutingReferenceEqualsDirectly()
{
var instanceUnderTest = new SomeService();
var mockHandler = new Mock<IOnAddEventHanlder>();
instanceUnderTest.OnAdd += mockHandler.Object.HandleOnAdd;
instanceUnderTest.Add(1, 2);
mockHandler.Verify(m => m.HandleOnAdd(
It.Is<object>(o => o.Equals(instanceUnderTest)),
It.IsAny<EventArgs>()));
}
}
In order to mock up on the event i created a helper interface (available only in test solution):
public interface IOnAddEventHanlder
{
void HandleOnAdd(object sender, EventArgs args);
}
As mentioned above:
SucceedingTest_DueToExecutingReferenceEqualsDirectly -> succeeds which is OK
FailingTest_DueToWrongEvalutionOfSameAsConstraint -> fails which is not OK
I'm using:
VS 2017
Nuint 3.12.0
Moq 4.12.0
NUnit3TestAdapter 3.13.0
Microsoft.NET.Test.SDK 16.2.0
.NET Core 2.2.0
The text was updated successfully, but these errors were encountered:
I haven't tested your code yet, but I assume that the problem is that you are attempting to use NUnit's Is.SameAs like a Moq argument matcher when it isn't one. So what's likely happening is that Moq will match the actual recorded argument value (an instance of SomeService) against the value produced by invoking Is.SameAs(instanceUnderTest) (an instance of SameAsConstraint).
You could wrap NUnit constraints as custom Moq argument matchers (which are basically functions calling Moq.Match.Create<TArg>), but is that really necessary? Since you're comparing raw values you don't really need any matcher at all for that first argument:
By checking equality of references, I faced a problem when I used NUnit SameAsConstraint (Is.SameAs(...)) in mocks verification method. The assertion evaluates to false, although both references are equal. By switching from NUnit SameAsConstraint to a direct comparison (e.g.: It.Is(input => input.Equals(sameReferenceAsInput)) performs flawless.
I created a small example to reproduce the issue:
Lets look at a simple class that adds two numbers an emits a proper event when calculation is performed. The sender argument of the event references the event sending instance following .Net framework design guidelines:
Then look at both tests doing exactly the same. The only difference is implementation of assertions:
In order to mock up on the event i created a helper interface (available only in test solution):
As mentioned above:
SucceedingTest_DueToExecutingReferenceEqualsDirectly -> succeeds which is OK
FailingTest_DueToWrongEvalutionOfSameAsConstraint -> fails which is not OK
I'm using:
The text was updated successfully, but these errors were encountered: