即使忽略该行为,也能通过自动固定装置获得循环引用

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

我有以下测试方法,我使用

AutoFixture.Xunit2
进行测试。

[UsesVerify]
public class UpdateWorkspaceTests : TestBase
{
    private readonly Fixture _fixture;
    public UpdateWorkspaceTests()
    {
        _fixture = new Fixture();
        _fixture.Behaviors.OfType<ThrowingRecursionBehavior>().ToList().ForEach(b => _fixture.Behaviors.Remove(b));
        _fixture.Behaviors.Add(new OmitOnRecursionBehavior(1));
    }

    [Theory, AutoData]
    public async Task UpdateWorkspace_ValidUpdate_OnUpdatedEvent(Workspace workspace)
    {     
        _dbContextMock.Setup(x => x.Set<Workspace>()).ReturnsDbSet(new List<Workspace> { workspace });
        _dbContextFactoryMock.Setup(f => f.CreateDbContextAsync(It.IsAny<CancellationToken>()))
                            .ReturnsAsync(_dbContextMock.Object);

        var request = new UpdateWorkspaceInput(
            workspace.Id,
            "Workspace2 - New Name",
            "Workspace2 - Description"
            );

        var handler = new UpdateWorkspaceHandler(_dbContextFactoryMock.Object, _eventSenderMock.Object);
        Workspace? updatedWorkspace = await handler.Handle(request, _cancellationToken);

        _eventSenderMock.Verify(
              mock => mock.SendAsync(
                  nameof(WorkspaceSubscriptions.OnUpdatedWorkspace),
                  updatedWorkspace,
                  _cancellationToken),
              Times.Once);
    }
}

在上面的代码中,我已经配置了

OmitOnRecursionBehavior
但仍然得到相同的异常,异常详细信息如下,

    Message: 
AutoFixture.ObjectCreationExceptionWithPath : AutoFixture was unable to create an instance of type AutoFixture.Kernel.SeededRequest because the traversed object graph contains a circular reference. Information about the circular path follows below. This is the correct behavior when a Fixture is equipped with a ThrowingRecursionBehavior, the default. This ensures that you are being made aware of circular references in your code. Your first reaction should be to redesign your API to get rid of all circular references. However, if this is not possible (most likely because parts or all of the API is delivered by a third party), you can replace this default behavior with a different behavior: on the Fixture instance, remove the ThrowingRecursionBehavior from Fixture.Behaviors, and instead add an instance of OmitOnRecursionBehavior:

fixture.Behaviors.OfType<ThrowingRecursionBehavior>().ToList()
    .ForEach(b => fixture.Behaviors.Remove(b));
fixture.Behaviors.Add(new OmitOnRecursionBehavior());

                

Request path:
    SchemaModeler.Domain.Organization DefaultOrganization
      SchemaModeler.Domain.User
        SchemaModeler.Domain.User User
          SchemaModeler.Domain.OrganizationUser
            System.Collections.Generic.IEnumerable`1[SchemaModeler.Domain.OrganizationUser]
              System.Collections.Generic.IEnumerable`1[SchemaModeler.Domain.OrganizationUser] collection
                System.Collections.Generic.List`1[SchemaModeler.Domain.OrganizationUser]
                  System.Collections.Generic.ICollection`1[SchemaModeler.Domain.OrganizationUser]
                    System.Collections.Generic.ICollection`1[SchemaModeler.Domain.OrganizationUser] Users
                      SchemaModeler.Domain.Organization
                        SchemaModeler.Domain.Organization Organization
                          SchemaModeler.Domain.Workspace
                            SchemaModeler.Domain.Workspace workspace


  Stack Trace: 
ThrowingRecursionHandler.HandleRecursiveRequest(Object request, IEnumerable`1 recordedRequests)
RecursionGuard.HandleRecursiveRequest(Object request)
ObsoletedMemberShims.RecursionGuard_HandleRecursiveRequest(RecursionGuard guard, Object request)
RecursionGuard.Create(Object request, ISpecimenContext context)
Fixture.Create(Object request, ISpecimenContext context)
SpecimenContext.Resolve(Object request)
SeedIgnoringRelay.Create(Object request, ISpecimenContext context)
CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context)
CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context)
Postprocessor`1.Create(Object request, ISpecimenContext context)
<208 more frames...>
Postprocessor`1.Create(Object request, ISpecimenContext context)
AutoPropertiesTarget.Create(Object request, ISpecimenContext context)
CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context)
TerminatingWithPathSpecimenBuilder.Create(Object request, ISpecimenContext context)
BehaviorRoot.Create(Object request, ISpecimenContext context)
RecursionGuard.Create(Object request, ISpecimenContext context)
Fixture.Create(Object request, ISpecimenContext context)
SpecimenContext.Resolve(Object request)
AutoDataAttribute.Resolve(ParameterInfo p)
AutoDataAttribute.GetData(MethodInfo testMethod)

  (result has additional output)

我不知道如何解决这个问题。有人可以通过任何其他解决方案帮助避免此循环引用问题吗?那我就非常感激了。

提前非常感谢!

c# asp.net-core entity-framework-core autofixture xunit2
1个回答
0
投票

我也遇到过同样的问题。用同样的策略。 可能还有其他使用 AutoFixture 的解决方案。

但是使用呢

_fixture.OmitAutoProperties = true;

相反?

这解决了我的问题

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