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.

Provide better feedback when call matcher throws

See original GitHub issue

Please 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: &lt;o =&gt; (o.get_Item("SomeName").ToObject() == "WrongValue")&gt;)
        /// 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: &lt;{
        /// "SomeName": "TestValue"
        /// }&gt;)
        /// 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:closed
  • Created 5 years ago
  • Comments:16 (16 by maintainers)

github_iconTop GitHub Comments

2reactions
thomaslevesquecommented, Apr 24, 2018

A means to write your own debug info is IMO the more important thing, to get the info you need rather then having FIE provide a converter for every class out there.

Well, it’s what custom formatters are for 😉

1reaction
blairconradcommented, Jul 3, 2018

This change has been released as part of FakeItEasy 4.7.0.

Thanks, @Mertsch. Look for your name in the release notes! 🥇

Read more comments on GitHub >

github_iconTop 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 >

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