{"action":"created","issue":{"url":"https://api.github.com/repos/AutoFixture/AutoFixture/issues/405","labels_url":"https://api.github.com/repos/AutoFixture/AutoFixture/issues/405/labels{/name}","comments_url":"https://api.github.com/repos/AutoFixture/AutoFixture/issues/405/comments","events_url":"https://api.github.com/repos/AutoFixture/AutoFixture/issues/405/events","html_url":"https://github.com/AutoFixture/AutoFixture/issues/405","id":77690308,"number":405,"title":"AutoConfiguredNSubstituteCustomization cannot set up override using Arg matching","user":{"login":"alexfoxgill","id":3819573,"avatar_url":"https://avatars.githubusercontent.com/u/3819573?v=3","gravatar_id":"","url":"https://api.github.com/users/alexfoxgill","html_url":"https://github.com/alexfoxgill","followers_url":"https://api.github.com/users/alexfoxgill/followers","following_url":"https://api.github.com/users/alexfoxgill/following{/other_user}","gists_url":"https://api.github.com/users/alexfoxgill/gists{/gist_id}","starred_url":"https://api.github.com/users/alexfoxgill/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alexfoxgill/subscriptions","organizations_url":"https://api.github.com/users/alexfoxgill/orgs","repos_url":"https://api.github.com/users/alexfoxgill/repos","events_url":"https://api.github.com/users/alexfoxgill/events{/privacy}","received_events_url":"https://api.github.com/users/alexfoxgill/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":6,"created_at":"2015-05-18T15:06:52Z","updated_at":"2015-06-05T14:14:01Z","closed_at":null,"body":"Substitutes created with the fixture using `AutoConfiguredNSubstituteCustomization` cannot subsequently be overridden using NSubstitute's `Arg` matching facility.\r\n\r\nThe following five test cases are all variations of the theme\r\n\r\n### Test Case 1: Pass\r\nThis test already exists in the project [here](https://github.com/AutoFixture/AutoFixture/blob/master/Src/AutoNSubstituteUnitTest/AutoConfiguredFixtureIntegrationTest.cs#L282). It sets up a substitute, calls a method, then mocks the method and calls it again to check that the returned value is the same as the mock. So far, so good!\r\n\r\n```CSharp\r\n[Fact]\r\npublic void SetupCallsOverrideValueFromFixture()\r\n{\r\n    var fixture = new Fixture().Customize(new AutoConfiguredNSubstituteCustomization());\r\n    var substitute = fixture.Create<IInterfaceWithMethod>();\r\n    var anonymousString = fixture.Create<string>();\r\n    var result1 = substitute.Method(anonymousString);\r\n\r\n    var expected = fixture.Create<string>();\r\n    substitute.Method(anonymousString).Returns(expected);\r\n\r\n    var result2 = substitute.Method(anonymousString);\r\n\r\n    Assert.NotEqual(result1, result2);\r\n    Assert.Equal(expected, result2);\r\n}\r\n```\r\n\r\n### Test Case 2: Pass\r\nThis is the same as the original test case, but *without* the initial call to the substitute's method. It still passes.\r\n\r\n```CSharp\r\n[Fact]\r\npublic void SetupCallsOverrideValueFromFixture2()\r\n{\r\n    var fixture = new Fixture().Customize(new AutoConfiguredNSubstituteCustomization());\r\n    var substitute = fixture.Create<IInterfaceWithMethod>();\r\n    var anonymousString = fixture.Create<string>();\r\n    //var result1 = substitute.Method(anonymousString);\r\n\r\n    var expected = fixture.Create<string>();\r\n    substitute.Method(anonymousString).Returns(expected);\r\n\r\n    var result2 = substitute.Method(anonymousString);\r\n\r\n    //Assert.NotEqual(result1, result2);\r\n    Assert.Equal(expected, result2);\r\n}\r\n```\r\n\r\n### Test Case 3: Fail\r\nThe above test case passes, but when we use NSubstitute's `Arg.Any<>` matching parameter to mock the method return, it *doesn't* return the expected result\r\n\r\n```CSharp\r\n[Fact]\r\npublic void SetupCallsOverrideValueFromFixture3()\r\n{\r\n    var fixture = new Fixture().Customize(new AutoConfiguredNSubstituteCustomization());\r\n    var substitute = fixture.Create<IInterfaceWithMethod>();\r\n    var anonymousString = fixture.Create<string>();\r\n    //var result1 = substitute.Method(anonymousString);\r\n\r\n    var expected = fixture.Create<string>();\r\n    substitute.Method(Arg.Any<string>()).Returns(expected);\r\n\r\n    var result2 = substitute.Method(anonymousString);\r\n\r\n    //Assert.NotEqual(result1, result2);\r\n    Assert.Equal(expected, result2);\r\n}\r\n```\r\n\r\n### Test Case 4: Fail\r\nIt's a similar story for the `Arg.Is<>` parameter matcher.\r\n\r\n```CSharp\r\n[Fact]\r\npublic void SetupCallsOverrideValueFromFixture4()\r\n{\r\n    var fixture = new Fixture().Customize(new AutoConfiguredNSubstituteCustomization());\r\n    var substitute = fixture.Create<IInterfaceWithMethod>();\r\n    var anonymousString = fixture.Create<string>();\r\n    //var result1 = substitute.Method(anonymousString);\r\n\r\n    var expected = fixture.Create<string>();\r\n    substitute.Method(Arg.Is<string>(_ => true)).Returns(expected);\r\n\r\n    var result2 = substitute.Method(anonymousString);\r\n\r\n    //Assert.NotEqual(result1, result2);\r\n    Assert.Equal(expected, result2);\r\n}\r\n```\r\n\r\n### Test Case 5: Pass\r\nThis is where it gets interesting. By uncommenting the first call to `substitute.Method`, we can use the `Arg.Any<>` matcher to return the expected value. It's not clear what's going on behind the scenes in NSubstitute here, but my guess is that calling the method somehow clears it for future stubbing.\r\n\r\n```CSharp\r\n[Fact]\r\npublic void SetupCallsOverrideValueFromFixture5()\r\n{\r\n    var fixture = new Fixture().Customize(new AutoConfiguredNSubstituteCustomization());\r\n    var substitute = fixture.Create<IInterfaceWithMethod>();\r\n    var anonymousString = fixture.Create<string>();\r\n    var result1 = substitute.Method(anonymousString);\r\n\r\n    var expected = fixture.Create<string>();\r\n    substitute.Method(Arg.Any<string>()).Returns(expected);\r\n\r\n    var result2 = substitute.Method(anonymousString);\r\n\r\n    Assert.NotEqual(result1, result2);\r\n    Assert.Equal(expected, result2);\r\n}\r\n```\r\n\r\nI hope that I explained the problem clearly! I took a look at the `AutoConfiguredNSubstituteCustomization` but I don't have any knowledge of the NSubstitue codebase so it was quite difficult to understand what was going on at a glance. Hopefully if I get some time I'll do some more in-depth reading."},"comment":{"url":"https://api.github.com/repos/AutoFixture/AutoFixture/issues/comments/109305695","html_url":"https://github.com/AutoFixture/AutoFixture/issues/405#issuecomment-109305695","issue_url":"https://api.github.com/repos/AutoFixture/AutoFixture/issues/405","id":109305695,"user":{"login":"alexfoxgill","id":3819573,"avatar_url":"https://avatars.githubusercontent.com/u/3819573?v=3","gravatar_id":"","url":"https://api.github.com/users/alexfoxgill","html_url":"https://github.com/alexfoxgill","followers_url":"https://api.github.com/users/alexfoxgill/followers","following_url":"https://api.github.com/users/alexfoxgill/following{/other_user}","gists_url":"https://api.github.com/users/alexfoxgill/gists{/gist_id}","starred_url":"https://api.github.com/users/alexfoxgill/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alexfoxgill/subscriptions","organizations_url":"https://api.github.com/users/alexfoxgill/orgs","repos_url":"https://api.github.com/users/alexfoxgill/repos","events_url":"https://api.github.com/users/alexfoxgill/events{/privacy}","received_events_url":"https://api.github.com/users/alexfoxgill/received_events","type":"User","site_admin":false},"created_at":"2015-06-05T14:14:01Z","updated_at":"2015-06-05T14:14:01Z","body":"@mrinaldi can you recommend a workaround for the case where I don't have a reference to the parameter that will be passed?"}}