لا يمكن العثور على المرجع الدائري للتثبيت التلقائي

StackOverflow https://stackoverflow.com//questions/22037616

  •  21-12-2019
  •  | 
  •  

سؤال

أنا أستخدم Autofixture لإنشاء نماذج الاختبار الخاصة بي، لكن في إحدى الحالات تظهر رسالة مفادها أن النموذج الخاص بي يحتوي على مرجع دائري لا يمكنني العثور عليه.النموذج الفاشل هو الطبقة RepresentationExpense والشيء الوحيد الذي يمكنني التفكير فيه هو أن الأمر متعلق بالميراث، منذ ذلك الحين Expense الفئة ليس لديها نفس المشكلة:

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

هنا هي رسالة الخطأ.ومع ذلك، فأنا لا أتبع المسار المذكور تمامًا.

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)
هل كانت مفيدة؟

المحلول

تمكنت من التكاثر عندما يكون هناك استثناء في المُنشئ.يمكنك تصحيح التعليمات البرمجية الخاصة بك والتحقق من الكائن الذي لا يجتاز "قسم التحقق".ثم يمكنك أن تحاول ذلك تجميد كائن صالح سيتم استخدامه في الاختبارات.أو يمكنك تخصيص التثبيت التلقائي باستخدام ISpecimenBuilder

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top