首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >找不到自动夹具循环引用

找不到自动夹具循环引用
EN

Stack Overflow用户
提问于 2014-02-26 09:50:58
回答 2查看 10.6K关注 0票数 10

我使用自动夹具来生成我的测试模型,但是在一个例子中,它说我的模型有一个循环引用,但我找不到。失败的模型是类RepresentationExpense,我唯一能想到的就是它与继承有关,因为Expense类没有相同的问题:

代码语言:javascript
复制
public class RepresentationExpense : Expense
{
    public string GuestName { get; private set; }
    public string GuestCompany { get; private set; }

    public RepresentationExpense(ExpenseId id, ExpenseReportId reportId, EmployeeId employeeId, string description, Payment payment, DateTime created, PaymentMethod paymentMethod, ReceiptId receiptId, string guestName, string guestCompany, string comment = null)
        : base(id, reportId, employeeId, description, payment, created, paymentMethod, CategoryType.Representation, receiptId, comment)
    {
        Verify.ArgumentNotNull(guestName, "guestName");
        Verify.ArgumentNotNull(guestCompany, "guestCompany");

        GuestName = guestName;
        GuestCompany = guestCompany;
    }
}

public class Expense
{
    public ExpenseId Id { get; private set; } // simple wrapper for long
    public ExpenseReportId ReportId { get; private set; } // simple wrapper for long
    public EmployeeId EmployeeId { get; private set; } // simple wrapper for long
    public Payment Payment { get; private set; }
    public DateTime Created { get; private set; }
    public PaymentMethod PaymentMethod { get; private set; } // enum
    public CategoryType CategoryType { get; private set; } // enum
    public ReceiptId ReceiptId { get; private set; } // simple wrapper for long
    public string Description { get; private set; }
    public string Comment { get; private set; }

    public Expense(ExpenseId id, ExpenseReportId reportId, EmployeeId employeeId, string description, Payment payment, DateTime created, PaymentMethod paymentMethod, CategoryType categoryType, ReceiptId receiptId, string comment = null)
    {
        Verify.ArgumentNotDefault(id, "id");
        Verify.ArgumentNotDefault(reportId, "reportId");
        Verify.ArgumentNotDefault(employeeId, "employeeId");
        Verify.ArgumentNotDefault(created, "created");
        Verify.ArgumentNotNull(categoryType, "category");
        Verify.ArgumentNotNull(payment, "payment");
        Verify.ArgumentNotNull(paymentMethod, "paymentMethod");
        Verify.ArgumentNotDefault(receiptId, "receipt");
        Verify.ArgumentNotNull(description, "description");
        Verify.Argument(receiptId != ReceiptId.Unassigned, "Must have an existing report");
        Verify.Argument(reportId != ExpenseReportId.Unassigned, "Must have an existing report");

        Id = id;
        ReportId = reportId;
        EmployeeId = employeeId;
        Created = created;
        CategoryType = categoryType;
        Payment = payment;
        PaymentMethod = paymentMethod;
        ReceiptId = receiptId;
        Description = description;
        Comment = comment;
    }
}

public sealed class Payment
{
    public Money Money { get; private set; } // simple class
    public ExchangeRate ExchangeRate { get; private set; } // simple class
    public DateTime Date { get; private set; }

    public Payment(Money money, ExchangeRate exchangeRate, DateTime date)
    {
        Verify.ArgumentNotNull(money, "money");
        Verify.ArgumentNotNull(exchangeRate, "exchangeRate");
        Verify.ArgumentNotDefault(date, "date");
        Verify.Argument(money.Currency.Name == exchangeRate.Currency.Name, "Currency must be the same for money and exchange rate");
        Verify.Operation(date <= DateTime.Now, "You cannot create a payment in the future");

        Money = money;
        ExchangeRate = exchangeRate;
        Date = date;
    }
}

这是错误消息。不过,我不太遵循上面提到的路线。

代码语言:javascript
复制
Ploeh.AutoFixture.Idioms.GuardClauseException : AutoFixture was unable to create an instance for parameter "payment" of method ".ctor".
Method Signature: Void .ctor(BLL.Modules.Expenses.Models.ExpenseId, BLL.Modules.Expenses.Models.ExpenseReportId, BLL.Modules.Expenses.Models.EmployeeId, System.String, BLL.Modules.Expenses.Models.Payment, System.DateTime, BLL.Modules.Expenses.Models.PaymentMethod, BLL.Modules.Expenses.Models.ReceiptId, System.String, System.String, System.String)
Declaring Type: BLL.Modules.Expenses.Models.RepresentationExpense
Reflected Type: BLL.Modules.Expenses.Models.RepresentationExpense
  ----> Ploeh.AutoFixture.ObjectCreationException : AutoFixture was unable to create an instance of type System.RuntimeType 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, which is 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 in order 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.
    Path:
        BLL.Modules.Expenses.Models.Payment --> 
        BLL.Modules.Expenses.Models.Payment payment --> 
        BLL.Modules.Expenses.Models.Payment
Result StackTrace:  
at Ploeh.AutoFixture.Idioms.GuardClauseAssertion.GetParameters(IMethod method)
at Ploeh.AutoFixture.Idioms.GuardClauseAssertion.GetParameterGuardCommands(IMethod method)
at Ploeh.AutoFixture.Idioms.GuardClauseAssertion.VerifyNormal(IMethod method)
at Ploeh.AutoFixture.Idioms.GuardClauseAssertion.Verify(IMethod method, Boolean isReturnValueIterator)
at Ploeh.AutoFixture.Idioms.GuardClauseAssertion.Verify(ConstructorInfo constructorInfo)
at Ploeh.AutoFixture.Idioms.IdiomaticAssertion.Verify(ConstructorInfo[] constructorInfos)
at Ploeh.AutoFixture.Idioms.IdiomaticAssertion.Verify(Type type)
at WorkxoneUnitTests.TestBase`1.AssertGuardClausesForType() in c:\Code\Comenxa\WorkxoneUnitTests\TestBase.cs:line 58
at WorkxoneUnitTests.BLL.Modules.Expenses.Models.RepresentationExpenseTests.Guards_are_asserted() in c:\Code\Comenxa\WorkxoneUnitTests\BLL\Modules\Expenses\Models\RepresentationExpenseTests.cs:line 24
--ObjectCreationException
at Ploeh.AutoFixture.Kernel.ThrowingRecursionHandler.HandleRecursiveRequest(Object request, IEnumerable`1 recordedRequests)
at Ploeh.AutoFixture.Kernel.RecursionGuard.HandleRecursiveRequest(Object request)
at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context)
at Ploeh.AutoFixture.Fixture.Create(Object request, ISpecimenContext context)
at Ploeh.AutoFixture.Kernel.SpecimenContext.Resolve(Object request)
at Ploeh.AutoFixture.Idioms.SpecimenBuilderComposer.CreateAnonymous(ISpecimenBuilder builder, Object request)
at Ploeh.AutoFixture.Idioms.GuardClauseAssertion.GetParameters(IMethod method)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-02-26 11:01:46

当构造函数中抛出异常时,我设法复制。您可以调试代码并检查哪个对象没有通过“验证部分”。然后,您可以尝试冰冻有效对象,该对象将用于测试。或者您可以使用ISpecimenBuilder自定义自动夹具

票数 2
EN

Stack Overflow用户

发布于 2021-04-20 08:36:59

我通过将夹具配置为忽略循环引用来解决这个问题。

代码语言:javascript
复制
var fixture = new Fixture();
foreach (var behavior in fixture.Behaviors.OfType<ThrowingRecursionBehavior>())
    fixture.Behaviors.Remove(behavior);
fixture.Behaviors.Add(new OmitOnRecursionBehavior());

请注意,来自我的fixture.Behaviors.Remove(new ThrowingRecursionBehavior())来源实际上不起作用

票数 14
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22037616

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档