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 9 months ago • 1 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