moq icon indicating copy to clipboard operation
moq copied to clipboard

Moq Setup does not work with "object" as generic type?

Open iqoOopi opened this issue 1 year ago • 2 comments

Moq Version: 4.20.70

I have one MediatR behavior like this:

public class RequestValidationBehaviour<TRequest, TResponse>(IEnumerable<IValidator<TRequest>> validators) : IPipelineBehavior<TRequest, TResponse> where TRequest : notnull
{

    public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
    {
        if (validators.Any())
        {
            var context = new ValidationContext<TRequest>(request);

            var validator1 = validators.First();

            var test = await validator1.ValidateAsync(context, cancellationToken);

            var validationResults = await Task.WhenAll(validators.Select(v => v.ValidateAsync(context, cancellationToken)));
            var failures = validationResults.SelectMany(r => r.Errors).Where(f => f != null).ToList();

            if (failures.Count != 0)
                throw new ValidationException(failures);
        }
        return await next();
    }
}

So I want to unit test it, my unit test is like:

        [Fact]
        public async Task Handle_InvalidRequest_ValidationExceptionThrown()
        {
            // Arrange
            var request = new object();
            var cancellationToken = CancellationToken.None;
            var validatorMock = new Mock<IValidator<object>>();

            validatorMock.Setup(v => v.ValidateAsync(It.IsAny<ValidationContext<object>>(), cancellationToken))
                     .ReturnsAsync(new ValidationResult(new List<ValidationFailure> { new("a", "b") }));

            var validators = new List<IValidator<object>>
                {
                    validatorMock.Object
                };

            var next = new Mock<RequestHandlerDelegate<object>>();
            var behaviour = new RequestValidationBehaviour<object, object>(validators);

            // Act & Assert
            await Assert.ThrowsAsync<Application.Common.Exceptions.ValidationException>(() => behaviour.Handle(request, next.Object, cancellationToken));
            next.Verify(x => x(), Times.Never);
        }
When I run the unit testing, the result is always null instead of the one in Setup call, wondering why?    

image

(updated in the comment, when using object as generic, moq won't work, however changed object to string then everything will work)

Back this issue Back this issue

iqoOopi avatar May 15 '24 22:05 iqoOopi

Interesting, if I modify my var request = new object(); just into var request = "test"; the testing will pass... image

is that Moq can not handle type "object"?

iqoOopi avatar May 15 '24 23:05 iqoOopi

Due to lack of recent activity, this issue has been labeled as 'stale'. It will be closed if no further activity occurs within 30 more days. Any new comment will remove the label.

github-actions[bot] avatar May 07 '25 01:05 github-actions[bot]