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

Verifying a protected method when the exact parameter types are not statically known #1339

Closed
martincostello opened this issue Apr 21, 2023 · 0 comments

Comments

@martincostello
Copy link

I've been trying to write a test for some functionality where a class has a large number of protected methods which are called based on dynamic deserialization behaviour.

Rather than a hand-rolled mock that needs maintaining, I instead wanted to leverage the existing data-driven tests for the deserialization to use the same approach.

However, the part where I've gotten stuck is that I don't know the type of the parameters on the protected methods at runtime, so I haven't been able to get the setup to work. I do however know what types the parameters will be derived from based on the pattern of conventions in the code.

This is as far as I managed to get:

[Theory]
[ClassData(typeof(WebhookEventProcessorTestsData))]
public async Task CanProcessAsync(WebhookHeaders headers, string payload, Type expectedType)
{
    var rawHeaders = new Dictionary<string, StringValues>()
    {
        ["X-GitHub-Event"] = new[] { headers.Event },
    };

    var typePrefix = expectedType.Name.Replace("Event", string.Empty);
    var methodName = $"Process{typePrefix}WebhookAsync";

    var mock = new Mock<WebhookEventProcessor>();
    mock.Protected()
        .Setup<Task>(methodName, false, ItExpr.IsAny<WebhookHeaders>(), ItExpr.IsAny<WebhookEvent>(), ItExpr.IsAny<WebhookEventAction>())
        .Verifiable();

    await mock.Object.ProcessWebhookAsync(rawHeaders, payload).ConfigureAwait(false);

    mock.Verify();
}

This fails to match the method as the type check here only works for a more derived-type matching a less derived-type on the declaration, but in my case as I don't know the specific type I wanted to match it the other way around (i.e. a parameter that is of this type):

https://github.com/moq/moq4/blob/1c4c72309bd1abf265974ffff9e3a72d5be0632a/src/Moq/Extensions.cs#L329

As I don't have a type parameter, I can't use ItExpr.IsAny<T>(), and ItExtra.IsAny<It.IsAnyType>() didn't seem to work either.

I see there's some extensibility around matching, but after much head-scratching I couldn't seem to find a way around it to get it to work the way I wanted it to.

Is what I'm trying to achieve even currently possible with Moq (#887 suggests maybe not)? If it is, any help on what I'm missing to get the setup and verify to work would be appreciated.

More context can be found here octokit/webhooks.net#244 (comment).

@martincostello martincostello closed this as not planned Won't fix, can't repro, duplicate, stale Nov 30, 2023
@devlooped devlooped locked and limited conversation to collaborators Sep 4, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant