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 counts multiple invocations although there is one when using capture #834

Closed
omerlh opened this issue May 29, 2019 · 3 comments
Closed

Comments

@omerlh
Copy link

omerlh commented May 29, 2019

I used moq to mock an object and assert it is called only once. For some reason, moq claims there are 2 invocations although there is only one.
This is the relevant part of my code:

            try
            {
                response = await mOpenPolicyAgent.Query(mConfiguration.QueryPath, request);
            }catch(ApiException e)
            {
                var decisionId = Guid.NewGuid().ToString();
                mLogger.LogError("OPA request failed {excpetion}, decision id: {decisionId}", e, decisionId);
                response = new OpenPolicyAgentQueryResponse
                {
                    Result = null,
                    DecisionId = decisionId
                };
            }
            
            mLogger.LogInformation("OPA returned {result}, decision id: {decisionId}",
                response.Result,
                response.DecisionId);

mOpenPolicyAgent is the mocked object. When debugging it, I noticed that before the line starting with mLogger there is only one invocation - but after this line there are 2.
This is the relevant part from my test code:

mOpenPolicyAgent = new Mock<IOpenPolicyAgent>();

mOpenPolicyAgent.Setup(x => x.Query("dummy", Capture.In(captures)))
                .Returns(Task.FromResult(new OpenPolicyAgentQueryResponse { Result = true}));

await mTarget.InvokeAsync(mHttpContext);

mOpenPolicyAgent.Verify(
                x => x.Query("dummy", It.IsAny<OpenPolicyAgentQueryRequest>()),
                Times.Once);

I removed the Capture.In(captures) and now it is working as expected. Is this the expected behavior?

@stakx
Copy link
Contributor

stakx commented May 29, 2019

@omerlh, could you derive a minimally complete & standalone code example from your code that we can run to reproduce this issue?

In short, no, Capture.In should not cause double invocations, so this might be a bug (either in your code, or in Moq).

Here's an example of what a short, self-contained repro code example might look like:

using System.Collections.Generic;
using System.Threading.Tasks;
using Moq;

public partial class OpenPolicyAgentQueryRequest { }
public partial class OpenPolicyAgentQueryResponse { }

public interface IOpenPolicyAgent
{
    Task<OpenPolicyAgentQueryResponse> Query(string path, OpenPolicyAgentQueryRequest request);
}

class Target
{
    private readonly IOpenPolicyAgent openPolicyAgent;

    public Target(IOpenPolicyAgent openPolicyAgent)
    {
        this.openPolicyAgent = openPolicyAgent;
    }

    public async Task InvokeAsync()
    {
        var request = new OpenPolicyAgentQueryRequest();
        var response = await this.openPolicyAgent.Query("dummy", request);
    }
}

class Program
{
    static async Task Main()
    {
        var captures = new List<OpenPolicyAgentQueryRequest>();

        var mOpenPolicyAgent = new Mock<IOpenPolicyAgent>();
        mOpenPolicyAgent.Setup(m => m.Query("dummy", Capture.In(captures)))
                        .Returns(Task.FromResult(new OpenPolicyAgentQueryResponse())); ;

        var mTarget = new Target(mOpenPolicyAgent.Object);
        await mTarget.InvokeAsync();

        mOpenPolicyAgent.Verify(m => m.Query("dummy", It.IsAny<OpenPolicyAgentQueryRequest>()), Times.Once);
    }
}

(Incidentally, the above doesn't exhibit the problem you described.)

@stakx
Copy link
Contributor

stakx commented Jun 5, 2019

I'll be closing this issue in a few days. There's not much (nothing, actually) that can be done without repro code.

@omerlh
Copy link
Author

omerlh commented Jun 6, 2019

Hey, sorry - somehow missed you original response, my bad. It was something with references that screw this up. I'll close this issue now, thanks!

@omerlh omerlh closed this as completed Jun 6, 2019
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