Provide better feedback when call matcher throws
See original GitHub issuePlease consider the following code and comments on it. As you can see in the examples, an exception in rule building makes finding the issue very hard, since you have no debug info at all, that is usually very rich with FIE
using System;
using FakeItEasy;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace FakeItEasyBugs
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void EverythingOkTest()
{
ICanDoSomething fake = A.Fake<ICanDoSomething>();
this.myApiCallGetsDataFromSomewhere(fake);
A.CallTo(() => fake.CallMe(A<JObject>.That.Matches(o =>
o["SomeName"].ToObject<string>() == "TestValue"))).MustHaveHappenedOnceExactly();
}
/// <summary>
/// Test method FakeItEasyBugs.UnitTest1.SlightChanceToFindTheErrorTest threw exception:
/// FakeItEasy.ExpectationException:
///
/// Assertion failed for the following call:
/// FakeItEasyBugs.ICanDoSomething.CallMe(o: <o => (o.get_Item("SomeName").ToObject() == "WrongValue")>)
/// Expected to find it once exactly but didn't find it among the calls:
/// 1: FakeItEasyBugs.ICanDoSomething.CallMe(o: [[[]]])
///
///
/// at FakeItEasy.Core.FakeAsserter.AssertWasCalled(Func`2 callPredicate, Action`1 callDescriber, CallCountConstraint callCountConstraint) in C:\projects\fakeiteasy\src\FakeItEasy\Core\FakeAsserter.cs:line 41
/// at FakeItEasy.Configuration.RuleBuilder.MustHaveHappened(CallCountConstraint callCountConstraint) in C:\projects\fakeiteasy\src\FakeItEasy\Configuration\RuleBuilder.cs:line 174
/// at FakeItEasyBugs.UnitTest1.SlightChanceToFindTheErrorTest()
/// </summary>
[TestMethod]
public void SlightChanceToFindTheErrorTest()
{
ICanDoSomething fake = A.Fake<ICanDoSomething>();
this.myApiCallGetsDataFromSomewhere(fake);
A.CallTo(() => fake.CallMe(A<JObject>.That.Matches(o =>
o["SomeName"].ToObject<string>() == "WrongValue")))
.MustHaveHappenedOnceExactly();
}
/// <summary>
/// Test method FakeItEasyBugs.UnitTest1.HaveNoIdeaWhatGoesWrongTest threw exception:
/// System.NullReferenceException: Object reference not set to an instance of an object.
/// at lambda_method(Closure , JObject )
/// at System.Linq.Enumerable.All[TSource](IEnumerable`1 source, Func`2 predicate)
/// at FakeItEasy.Configuration.RuleBuilder.RuleMatcher.Matches(IFakeObjectCall call) in C:\projects\fakeiteasy\src\FakeItEasy\Configuration\RuleBuilder.cs:line 322
/// at System.Linq.Enumerable.Count[TSource](IEnumerable`1 source, Func`2 predicate)
/// at FakeItEasy.Core.FakeAsserter.AssertWasCalled(Func`2 callPredicate, Action`1 callDescriber, CallCountConstraint callCountConstraint) in C:\projects\fakeiteasy\src\FakeItEasy\Core\FakeAsserter.cs:line 34
/// at FakeItEasy.Configuration.RuleBuilder.MustHaveHappened(CallCountConstraint callCountConstraint) in C:\projects\fakeiteasy\src\FakeItEasy\Configuration\RuleBuilder.cs:line 172
/// at FakeItEasyBugs.UnitTest1.HaveNoIdeaWhatGoesWrongTest()
/// </summary>
[TestMethod]
public void HaveNoIdeaWhatGoesWrongTest()
{
ICanDoSomething fake = A.Fake<ICanDoSomething>();
this.myApiCallGetsDataFromSomewhere(fake);
A.CallTo(() => fake.CallMe(A<JObject>.That.Matches(o =>
o["Misspelled"].ToObject<string>() == "TestValue")))
.MustHaveHappenedOnceExactly();
}
/// <summary>
/// Test method FakeItEasyBugs.UnitTest1.TryingToHackSomeDebugInfoTest threw exception:
/// FakeItEasy.ExpectationException:
///
/// Assertion failed for the following call:
/// FakeItEasyBugs.ICanDoSomething.CallMe(o: <{
/// "SomeName": "TestValue"
/// }>)
/// Expected to find it once exactly but didn't find it among the calls:
/// 1: FakeItEasyBugs.ICanDoSomething.CallMe(o: [[[]]])
///
///
/// at FakeItEasy.Core.FakeAsserter.AssertWasCalled(Func`2 callPredicate, Action`1 callDescriber, CallCountConstraint callCountConstraint) in C:\projects\fakeiteasy\src\FakeItEasy\Core\FakeAsserter.cs:line 41
/// at FakeItEasy.Configuration.RuleBuilder.MustHaveHappened(CallCountConstraint callCountConstraint) in C:\projects\fakeiteasy\src\FakeItEasy\Configuration\RuleBuilder.cs:line 174
/// at FakeItEasyBugs.UnitTest1.TryingToHackSomeDebugInfoTest()
/// </summary>
[TestMethod]
public void TryingToHackSomeDebugInfoTest()
{
ICanDoSomething fake = A.Fake<ICanDoSomething>();
JObject fakeParamRecieved = null;
A.CallTo(() => fake.CallMe(A<JObject>.Ignored)).Invokes((JObject o) => fakeParamRecieved = o);
this.myApiCallGetsDataFromSomewhere(fake);
A.CallTo(() => fake.CallMe(A<JObject>.That.Matches(o =>
o["SomeName"].ToObject<string>() == "WrongValue", io => io.Write(JsonConvert.SerializeObject(fakeParamRecieved, Formatting.Indented)))))
.MustHaveHappenedOnceExactly();
}
/// <summary>
/// Test method FakeItEasyBugs.UnitTest1.MyDebugInfoIsCompletelyLostTest threw exception:
/// System.NullReferenceException: Object reference not set to an instance of an object.
/// at lambda_method(Closure , JObject )
/// at System.Linq.Enumerable.All[TSource](IEnumerable`1 source, Func`2 predicate)
/// at FakeItEasy.Configuration.RuleBuilder.RuleMatcher.Matches(IFakeObjectCall call) in C:\projects\fakeiteasy\src\FakeItEasy\Configuration\RuleBuilder.cs:line 322
/// at System.Linq.Enumerable.Count[TSource](IEnumerable`1 source, Func`2 predicate)
/// at FakeItEasy.Core.FakeAsserter.AssertWasCalled(Func`2 callPredicate, Action`1 callDescriber, CallCountConstraint callCountConstraint) in C:\projects\fakeiteasy\src\FakeItEasy\Core\FakeAsserter.cs:line 34
/// at FakeItEasy.Configuration.RuleBuilder.MustHaveHappened(CallCountConstraint callCountConstraint) in C:\projects\fakeiteasy\src\FakeItEasy\Configuration\RuleBuilder.cs:line 172
/// at FakeItEasyBugs.UnitTest1.MyDebugInfoIsCompletelyLostTest()
/// </summary>
[TestMethod]
public void MyDebugInfoIsCompletelyLostTest()
{
ICanDoSomething fake = A.Fake<ICanDoSomething>();
JObject fakeParamRecieved = null;
A.CallTo(() => fake.CallMe(A<JObject>.Ignored)).Invokes((JObject o) => fakeParamRecieved = o);
this.myApiCallGetsDataFromSomewhere(fake);
A.CallTo(() => fake.CallMe(A<JObject>.That.Matches(o =>
o["Misspelled"].ToObject<string>() == "WrongValue", io => io.Write(JsonConvert.SerializeObject(fakeParamRecieved, Formatting.Indented))))) // IO is ignored comepletely
.MustHaveHappenedOnceExactly();
}
[TestMethod]
public void WhatIWhishForTest()
{
ICanDoSomething fake = A.Fake<ICanDoSomething>();
this.myApiCallGetsDataFromSomewhere(fake);
A.CallTo(() => fake.CallMe(A<JObject>.That.Matches(o => o["Misspelled"].ToObject<string>() == "TestValue"
// Here I can print any kind of info about the call I expected with the actual value
//, (IFakeObjectCall c, IOutputWriter io) => io.Write(JsonConvert.SerializeObject(c.Arguments, Formatting.Indented))
)))
.MustHaveHappenedOnceExactly();
}
/// <summary>
/// This method gives me data I have no clue about!
/// </summary>
private void myApiCallGetsDataFromSomewhere(ICanDoSomething fake)
{
JObject testObject = new JObject();
testObject.Add("SomeName", JToken.FromObject("TestValue"));
fake.CallMe(testObject);
}
}
public interface ICanDoSomething
{
void CallMe(JObject o);
}
}
Issue Analytics
- State:
- Created 5 years ago
- Comments:16 (16 by maintainers)
Top Results From Across the Web
Mockito: InvalidUseOfMatchersException - java
This exception may occur if matchers are combined with raw values: //incorrect: someMethod(anyObject(), "raw String"); When using matchers, all ...
Read more >4. Matchers in Depth - JavaScript Testing with Jasmine [Book]
Perhaps the simplest matcher in Jasmine is toEqual . It simply checks if two things are equal (and not necessarily the same exact...
Read more >Testing Exceptions with Spring MockMvc
In this short article, we'll see how exceptions should be thrown in our controllers and how to test these exceptions using Spring MockMvc....
Read more >Feedback | Apple Developer Documentation
Feedback helps people know what's happening, discover what they can do next, understand the results of actions, and avoid mistakes.
Read more >Solved When we call a method that might throw an exception
To help handle this situation, create a public class called ResultMightThrow. It stores the result of calling a method that might throw: either...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Well, it’s what custom formatters are for 😉
This change has been released as part of FakeItEasy 4.7.0.
Thanks, @Mertsch. Look for your name in the release notes! 🥇