.net Autofixture Xunit应该抛出但没有

fhity93d  于 2023-08-08  发布在  .NET
关注(0)|答案(1)|浏览(91)

我正在使用autofixture和autodata为我的服务编写单元测试。这就是考验

[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);
}


如您所见,我设置了服务中使用的repository,如果传递了任何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;
    }
}

rhfm7lfc

rhfm7lfc1#

更新: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);
}

字符串
但这并不可取,因为您要测试实际的服务

相关问题