Autofixture Xunit 应该抛出但没有抛出

问题描述 投票:0回答:1

我正在使用自动固定装置和自动数据为我的服务编写单元测试。这就是测试。

[Theory]
[AutoMoqData]
public async Task GetByIdAsync_WhenInvalidId_ShouldThrowNotFoundException(
    Mock<IReviewRepository> repositoryMock,
    IReviewService service)
    {
    // Arrange
    repositoryMock.Setup(r => r.GetByIdAsync(It.IsAny<int>()))
        .ReturnsAsync(value: null);

    // Act
    var act = () => service.GetByIdAsync(It.IsAny<int>());

    await act.Should().ThrowAsync<NotFoundException>()
        .WithMessage(ErrorMessages.REVIEW_NOT_FOUND);
        }

这就是正在测试的服务方法

public async Task<Review> GetByIdAsync(int id)
{
    var foundReview = await _repository.GetByIdAsync(id);

    if (foundReview == null)
    {
        Log.Error("Review with id = {@id} not found", id);
        throw new NotFoundException(ErrorMessages.REVIEW_NOT_FOUND);
    }

    return _mapper.Map<Review>(foundReview);
}

如您所见,我设置了服务中使用的存储库,以便在传递任何 int 时返回 null,以便我可以检查服务是否正确抛出我的自定义异常以及恒定的错误消息。 然后我创建我的方法的委托并测试我需要的内容。但测试失败并显示消息:

Message: 
    Expected a <SecondMap.Services.StoreManagementService.BLL.Exceptions.NotFoundException> to be thrown, but no exception was thrown.

  Stack Trace: 
    XUnit2TestFramework.Throw(String message)
    TestFrameworkProvider.Throw(String message)
    DefaultAssertionStrategy.HandleFailure(String message)
    AssertionScope.FailWith(Func`1 failReasonFunc)
    AssertionScope.FailWith(Func`1 failReasonFunc)
    AssertionScope.FailWith(String message)
    DelegateAssertionsBase`2.ThrowInternal[TException](Exception exception, String because, Object[] becauseArgs)
    AsyncFunctionAssertions`2.ThrowAsync[TException](String because, Object[] becauseArgs)
    ExceptionAssertionsExtensions.WithMessage[TException](Task`1 task, String expectedWildcardPattern, String because, Object[] becauseArgs)
    ReviewServiceTests.GetByIdAsync_WhenInvalidId_ShouldThrowNotFoundException(Mock`1 repositoryMock, IReviewService service) line 59
    --- End of stack trace from previous location ---

我已经手动测试过,该方法按预期工作,所以我认为问题出在自动夹具设置上,但还不能完全理解它。这是 AutoMoqDataAttribute 以防有帮助

public class AutoMoqDataAttribute : AutoDataAttribute
{
    public AutoMoqDataAttribute() : base(CreateFixture)
    {
            
    }

    private static IFixture CreateFixture()
    {
        var fixture = new Fixture();
        fixture.Customize(new AutoMoqCustomization { ConfigureMembers = true });
        return fixture;
    }
}
c# asp.net .net xunit autofixture
1个回答
0
投票

更新:TR;DR的解决方案:将IService更改为Service。 说明:调试表明,如果您传递服务的接口而不是实际的类,则 autofixture 将创建 Mock,而该 Mock 不会按照预期的方式运行,因此要么将 IService 更改为 Service,要么如果您确实想使用服务你可以像这样创建定制

public class AutoMoqDataAttribute : AutoDataAttribute
{
    public AutoMoqDataAttribute() : base(CreateFixture)
    {
            
    }

    private static IFixture CreateFixture()
    {
        var fixture = new Fixture();
        fixture.Customize(new CompositeCustomization(
            new AutoMoqCustomization { ConfigureMembers = true },
            new ServiceCustomization()));
            return fixture;
    }
}

public class ServiceCustomization : ICustomization
{
    public void Customize(IFixture fixture)
    {
        fixture.Register<IReviewService>(CreateReviewService);
        fixture.Register<IScheduleService>(CreateScheduleService);
        fixture.Register<IStoreService>(CreateStoreService);
        fixture.Register<IUserService>(CreateUserService);
    }

    private static ReviewService CreateReviewService() => new ReviewService(new Mock<IReviewRepository>().Object, new Mock<IMapper>().Object);

    private static ScheduleService CreateScheduleService() => new ScheduleService(new Mock<IScheduleRepository>().Object, new Mock<IMapper>().Object);

    private static StoreService CreateStoreService() => new StoreService(new Mock<IStoreRepository>().Object, new Mock<IMapper>().Object);

    private static UserService CreateUserService() => new UserService(new Mock<IUserRepository>().Object, new Mock<IMapper>().Object);
} 

但这确实不是优选的,因为你想测试实际服务

© www.soinside.com 2019 - 2024. All rights reserved.