NSubstitute - TestFixture 1 causes AmbiguousArgumentsException in TestFixture 2

前端 未结 3 713
[愿得一人]
[愿得一人] 2021-02-08 10:14

I am writing C# unit tests using NUnit and NSubstitute. I am testing a class which will attempt to retrieve objects from a config provider implementing the following interface:<

相关标签:
3条回答
  • 2021-02-08 10:49

    Ambiguous arguments is when NSubstitute compares the arguments to the call it is currently working with, to the stack of "argument matchers" it has (each time Arg.Blah is called, an the argument matcher is added to that stack), and it is unable to resolve which argument goes where.

    Normally this is caused by having a call like blah(null, null), with a single argument matcher queued up, but it can also be caused by the stack getting out-of-sync due to an arg matcher being used outside of call configuration, or as an argument to a non-virtual method.

    Version 1.8.0 (released after your question) includes slightly improved detection of the latter case, so that may be worth trying.

    Other than that, I've had this problem a few times and have used the following (painful) approach.

    • run the test in isolation and ensure it passes
    • work out what test runs immediately proceeding (can usually guess, but test logs can help here), and run just those two tests. Confirm it fails.
    • Look for any calls to Arg.xyz that could queue up an argument matcher in either test. Make sure it is used as part of a call configuration. Sometimes working out which call is problematic can be done by commenting out lines or replacing arg matchers with other values.
    • Make sure there are no calls to non-virtual methods that are confusing NSubstitute.

    Sometimes the problem may be due to a previous fixture, so you may need to workout the previous fixture and explore there as well. :(

    0 讨论(0)
  • 2021-02-08 10:49

    Changing the order of my tests worked. Not a great answer, but worked - do try!

    0 讨论(0)
  • 2021-02-08 10:50

    I had similar errors that started when I switched Microsoft test runner to VSTest.Console (they did not happened when running under MSTest.exe).  

    As it was advised in David's answer, the errors were caused by calls to non-substituted methods with Arg.* parameters. Arg.Any were passed to actual code methods, that where called without Returns or Received relevant methods.

    To scan my test library for such issues I used search with regular expression to find rows with Arg. but not Arg. following by Returns or preceded by Received

    (?=^.*Arg.*$)(?=^((?!Arg.*\.Returns).)*$)^((?!\.Received\(.*Arg.).)*$
    

    It's not bullet proof filter (e.g it doesn't exclude multi-line statements), but it helps to reduce number of calls to check.

    0 讨论(0)
提交回复
热议问题