{"action":"created","issue":{"url":"https://api.github.com/repos/FakeItEasy/FakeItEasy/issues/532","labels_url":"https://api.github.com/repos/FakeItEasy/FakeItEasy/issues/532/labels{/name}","comments_url":"https://api.github.com/repos/FakeItEasy/FakeItEasy/issues/532/comments","events_url":"https://api.github.com/repos/FakeItEasy/FakeItEasy/issues/532/events","html_url":"https://github.com/FakeItEasy/FakeItEasy/issues/532","id":103692177,"number":532,"title":"Asserting properties of an anonymous object called by Fake","user":{"login":"alexjamesbrown","id":437743,"avatar_url":"https://avatars.githubusercontent.com/u/437743?v=3","gravatar_id":"","url":"https://api.github.com/users/alexjamesbrown","html_url":"https://github.com/alexjamesbrown","followers_url":"https://api.github.com/users/alexjamesbrown/followers","following_url":"https://api.github.com/users/alexjamesbrown/following{/other_user}","gists_url":"https://api.github.com/users/alexjamesbrown/gists{/gist_id}","starred_url":"https://api.github.com/users/alexjamesbrown/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alexjamesbrown/subscriptions","organizations_url":"https://api.github.com/users/alexjamesbrown/orgs","repos_url":"https://api.github.com/users/alexjamesbrown/repos","events_url":"https://api.github.com/users/alexjamesbrown/events{/privacy}","received_events_url":"https://api.github.com/users/alexjamesbrown/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2015-08-28T10:21:12Z","updated_at":"2015-08-29T10:14:20Z","closed_at":null,"body":"Suppose I have a method that looks like this\r\n\r\n```c#\r\npublic async Task<IEnumerable<PhoneNumber>> GetPhoneNumbers(string accountId)\r\n{\r\n    return await _restClient.Get<IEnumerable<PhoneNumber>>(url, new\r\n    {\r\n        accountId = accountId\r\n    });\r\n}\r\n```\r\n\r\nI want to test that the `_restClient` was called with a given url, but more importantly, assert the anonymous object it was called with...\r\n\r\nI've come up with the following, but it seems a bit clunky -\r\n\r\n```c#\r\n[TestMethod]\r\npublic async Task Calls_api_with_account_id()\r\n{\r\n    object objectCalledWith = null;\r\n    string urlCalledWith = \"\";\r\n\r\n    A.CallTo(() => _fakeRestClient.Get<IEnumerable<PhoneNumber>>(A<string>._, A<object>._))\r\n        .Invokes((string url, object obj) =>\r\n        {\r\n            urlCalledWith = url;\r\n            objectCalledWith = obj;\r\n        })\r\n        .Returns(new List<PhoneNumber>());\r\n\r\n    var result = await _classUnderTest.GetPhoneNumbers(\"abc123\");\r\n\r\n    Assert.AreEqual(LatitudeAPIUrls.PhoneUrl, urlCalledWith);\r\n    Assert.IsTrue(objectCalledWith.ToDynamic().accountId == \"abc123\");\r\n}\r\n```\r\n\r\nI used the `DynamicExtensions` class found here: http://blog.jorgef.net/2011/06/converting-any-object-to-dynamic.html\r\n\r\n```c#\r\npublic static class DynamicExtensions\r\n{\r\n    public static dynamic ToDynamic(this object value)\r\n    {\r\n        IDictionary<string, object> expando = new ExpandoObject();\r\n\r\n        foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(value.GetType()))\r\n            expando.Add(property.Name, property.GetValue(value));\r\n\r\n        return (ExpandoObject)expando;\r\n    }\r\n}\r\n```\r\nJust wondering if there's a better / more built in way?"},"comment":{"url":"https://api.github.com/repos/FakeItEasy/FakeItEasy/issues/comments/135968467","html_url":"https://github.com/FakeItEasy/FakeItEasy/issues/532#issuecomment-135968467","issue_url":"https://api.github.com/repos/FakeItEasy/FakeItEasy/issues/532","id":135968467,"user":{"login":"blairconrad","id":3275797,"avatar_url":"https://avatars.githubusercontent.com/u/3275797?v=3","gravatar_id":"","url":"https://api.github.com/users/blairconrad","html_url":"https://github.com/blairconrad","followers_url":"https://api.github.com/users/blairconrad/followers","following_url":"https://api.github.com/users/blairconrad/following{/other_user}","gists_url":"https://api.github.com/users/blairconrad/gists{/gist_id}","starred_url":"https://api.github.com/users/blairconrad/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/blairconrad/subscriptions","organizations_url":"https://api.github.com/users/blairconrad/orgs","repos_url":"https://api.github.com/users/blairconrad/repos","events_url":"https://api.github.com/users/blairconrad/events{/privacy}","received_events_url":"https://api.github.com/users/blairconrad/received_events","type":"User","site_admin":false},"created_at":"2015-08-29T10:14:20Z","updated_at":"2015-08-29T10:14:20Z","body":"Ah, a predicate that reflects saves the day.\r\n\r\n```c#\r\nA.CallTo(() => _fakeRestClient.Get<IEnumerable<string>>(expectedUrl,\r\n    A<object>.That.Matches(\r\n    anon => anon.GetType().GetProperty(\"accountId\").GetValue(anon).Equals(expectedAccountId))))\r\n    .MustHaveHappened();\r\n```\r\n\r\nOf course, the error message on a mismatch isn't stellar in this case:\r\n\r\n```\r\n  Assertion failed for the following call:\r\n    FakeItEasyQuestions.IRestClient.Get<System.Collections.Generic.IEnumerable<System.String>>(\"URL: abcd1234\", <anon => anon.GetType().GetProperty(\"accountId\").GetValue(anon).Equals(\"abcd1234\")>)\r\n\r\n  Expected to find it at least once but found it #0 times among the calls:\r\n\r\n    1: FakeItEasyQuestions.IRestClient.Get<System.Collections.Generic.IEnumerable<System.String>>(url: \"URL: abc123\", o: { accountId = abc123 })\r\n```\r\n\r\nbut one can work with it.\r\n\r\nAlternatively, you could jazz this up with a description of the predicate:\r\n\r\n```csharp\r\nA.CallTo(() => _fakeRestClient.Get<IEnumerable<string>>(expectedUrl,\r\n    A<object>.That.Matches(\r\n    anon => anon.GetType().GetProperty(\"accountId\").GetValue(anon).Equals(expectedAccountId),\r\n    \"an object with account ID {0}\", expectedAccountId)))\r\n    .MustHaveHappened();\r\n```\r\n\r\nyields\r\n\r\n```\r\nFakeItEasy.ExpectationException : \r\n  Assertion failed for the following call:\r\n\r\n    FakeItEasyQuestions.IRestClient.Get<System.Collections.Generic.IEnumerable<System.String>>(\"URL: abcd1234\", <an object with account ID abcd1234>)\r\n\r\n  Expected to find it at least once but found it #0 times among the calls:\r\n\r\n    1: FakeItEasyQuestions.IRestClient.Get<System.Collections.Generic.IEnumerable<System.String>>(url: \"URL: abc123\", o: { accountId = abc123 })\r\n```\r\n\r\n(Or just extract the predicate to a method:\r\n\r\n```\r\nA.CallTo(() => _fakeRestClient.Get<IEnumerable<string>>(\r\n    expectedUrl,\r\n    A<object>.That.Matches(anon => IsAccountIdExpected(anon, expectedAccountId))))\r\n    .MustHaveHappened();\r\n```\r\n\r\n```c#\r\nFakeItEasy.ExpectationException : \r\n  Assertion failed for the following call:\r\n\r\n    FakeItEasyQuestions.IRestClient.Get<System.Collections.Generic.IEnumerable<System.String>>(\"URL: abcd1234\", <anon => IsAccountIdExpected(anon, \"abcd1234\")>)\r\n\r\n  Expected to find it at least once but found it #0 times among the calls:\r\n\r\n    1: FakeItEasyQuestions.IRestClient.Get<System.Collections.Generic.IEnumerable<System.String>>(url: \"URL: abc123\", o: { accountId = abc123 })\r\n```"}}