Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Moq "set" matcher fails when setting StringValues with string #1465

Open
mpdelbuono opened this issue Mar 20, 2024 · 1 comment
Open

Moq "set" matcher fails when setting StringValues with string #1465

mpdelbuono opened this issue Mar 20, 2024 · 1 comment

Comments

@mpdelbuono
Copy link

mpdelbuono commented Mar 20, 2024

Describe the Bug

Using the code shown below, we get the following error:

System.ArgumentException : Could not determine the correct positions for all argument matchers (1 in total) used in a call to this method: IHeaderDictionary.set_Location.
This could be caused by an unrecognized type conversion, coercion, narrowing, or widening, and is most likely a bug in Moq. Please report your use case to the Moq team.

We suspect the cause must be the coercion from string to StringValues via the implicit conversion operator. When using It.Is<StringValues>() the code works flawlessly.

Steps to Reproduce

The following code reproduces this behavior:

public class ReproTest
{
  [Fact]
  public void Repro()
  {
    Mock<HttpContext> context = new(MockBehavior.Strict);
    context.SetupSet(m => m.Response.Headers.Location = It.Is<string>(s => s.Contains("foo")));
    context.Object.Response.Headers.Location = "https://example.com/foo";
  }
}

Expected Behavior

Not crashing in this way. At a minimum, an error message indicating what was invalid about the matcher. Ideally, it would allow this coercion, since it heavily matches the code under test.

Exception with Stack Trace

System.ArgumentException : Could not determine the correct positions for all argument matchers (1 in total) used in a call to this method: IHeaderDictionary.set_Location.
This could be caused by an unrecognized type conversion, coercion, narrowing, or widening, and is most likely a bug in Moq. Please report your use case to the Moq team.

   at Moq.ActionObserver.<ReconstructExpression>g__GetArgumentExpressions|0_0[T](Invocation invocation, Match[] matches) in /_/src/Moq/ActionObserver.cs:line 197
   at Moq.ActionObserver.ReconstructExpression[T](Action`1 action, Object[] ctorArgs) in /_/src/Moq/ActionObserver.cs:line 53
   at Moq.Mock`1.SetupSet(Action`1 setterExpression) in /_/src/Moq/Mock`1.cs:line 711

Version Info

Tested on Moq 4.20.69 and 4.20.70

The test case above uses the following NuGet packages:

  • Microsoft.AspNetCore.App.Ref 8.0.3
  • Microsoft.Extensions.Features 8.0.3

Additional Info

@mpdelbuono mpdelbuono added the bug label Mar 20, 2024
@kzu
Copy link
Contributor

kzu commented May 5, 2024

Would gladly accept a PR for this enhancement.

Argument types must match exactly, so it's working as designed.

This could be enhanced in that PR by looking at implicit operators, but that adds another reflection lookup and invocation.

@kzu kzu added enhancement and removed bug labels May 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants