【问题标题】:C#, xUnit class object reference conflict in other test classesC#、xUnit类对象引用在其他测试类中冲突
【发布时间】:2021-10-26 12:25:56
【问题描述】:

我有 .NET CORE 5 应用程序,其中包含用 xUnit 编写的测试以及夹具和最小起订量。我的对象是期望行为的一部分。

我已经创建了它的实例并相应地分配了值。此类属性之一是CustomMessage

问题是在此对象的一个​​测试类中分配的值与其他测试类冲突。因此,如果我按类单独运行测试,那么它会通过,如果我一次性运行所有测试,它就会失败。问题是queryResultSiteSummaryMoq 对象。

QueryResultSummary 类

public class QueryResultSummary
{
    public int RecordsCount { get; set; }
    public bool IsRecordExist { get; set; }
    public bool Error { get; set; }
    public string ExecutionMessage { get; set; }
    public string CustomMessage { get; set; }
    public Exception Exceptions { get; set; }
}   

测试方法

[Fact]
[Trait("Method", "GetSite")]
[Description("Site found, then return type must be of SiteWithStatusDataView In ResponseObject")]
public async Task ShouldReturn_SiteWithStatusDataView_Type_IfExist()
{
    //Arrange
    var fixture = new Fixture();

    int siteId = 3086;
    long lastUpdatedDateTimeUTC = 1628895600000;
    DateTime registeredLastUpdatedDateTimeInRecord = DateTime.Parse("10/08/2021 10:33:40");

    var lastUpdatedDateTime = DateTimeCalculationHelper.ConvertMillisecondToDateTime(lastUpdatedDateTimeUTC).DateTime;

    var lastUpdatedDateTimeWithMilliSecond = DateServices.RemoveMilliSecond(lastUpdatedDateTime);

    string SiteSearchStatus = $"Request, Processed With Provided LastDateTime: {lastUpdatedDateTimeWithMilliSecond} With Actual LastDateTime: {registeredLastUpdatedDateTimeInRecord}";

    fixture.Customize<SiteDataView>(c => c
        .With(x => x.SiteId, siteId)
        .With(x => x.IsActive, true)
        .With(x => x.IsDeleted, false)
        .With(x => x.UpdatedDateTimeUTC, registeredLastUpdatedDateTimeInRecord)
    );

    var siteMoq = fixture.Create<SiteDataView>();

    getSiteQueryMoq.Setup(x => x.SiteId).Returns(siteId);
    getSiteQueryMoq.Setup(x => x.Execute()).ReturnsAsync((1, siteMoq));

    var siteWithStatusDataViewMoq = new SiteWithStatusDataView
    {
        IsLastUpdateDateTimeProvided = true,
        IsSiteModified = RecordStatusEnum.Yes.ToString(),
        Site = siteMoq
    };

    //issue is following object
    var queryResultSiteSummaryMoq = new QueryResultSummary
    {
        RecordsCount = siteMoq == null ? 0 : 1,
        IsRecordExist = true,
        Error = false,
        ExecutionMessage = QueryExecutionStatusEnum.Success.ToString(),
        Exceptions = (Exception)null,
        CustomMessage = SiteSearchStatus
    };

    var expectedResult = (siteWithStatusDataViewMoq, queryResultSiteSummaryMoq);

    //Act
    var actualData = await sut.GetSite(siteId, lastUpdatedDateTimeUTC);
    var extractedActualResult = actualData;

    //Assert
    extractedActualResult.Should().BeEquivalentTo(expectedResult);
    Assert.IsAssignableFrom<SiteWithStatusDataView>(extractedActualResult.Item1);

    queryResultSiteSummaryMoq = null;
}        

我也试过了,但还是不行

fixture.Customize<QueryResultSummary>(c => c
 .With(x => x.RecordsCount, exemptions == null ? 0 : exemptions.Count)
 .With(x => x.IsRecordExist, true)
 .With(x => x.Error, false)
 .With(x => x.ExecutionMessage, QueryExecutionStatusEnum.Success.ToString())
 .With(x => x.Exceptions, (Exception)null)
 .With(x => x.CustomMessage, string.Empty)
);            

【问题讨论】:

  • 所以如果我按类单独运行测试,那么它会通过,如果我一次性运行所有测试,它会失败。 >> 这可能表明你有一个共享组件在测试用例之间未正确重置的测试用例之间。你有什么分享?
  • 你有多个测试的问题,你能展示整个测试类吗?
  • @PeterCsala 我有类 QueryResultSummary 用于所有类,但我在为特定测试用例创建时创建新实例。即 var queryResultSummary = new QueryResultSummary{... //在此处设置属性值以满足每个类 }
  • 那您能否详细说明一下问题是queryResultSiteSummaryMoq 对象。

标签: moq xunit .net-5 xunit.net autofixture


【解决方案1】:

两个测试类相互干扰的最可能原因是它们共享某种状态,这是一种常见的不良做法,违反了F.I.R.S.T 原则。

由于sut 实例和其他一些对象没有在测试中声明,所以我假设您有某种设置阶段来声明它们。确保在测试运行之间没有任何共享实例存在,并且在测试类之间没有共享资源(对象实例)。

由于您使用 AutoFixture,请考虑将设置委托给 Fixture 实例。这将使您的测试更容易相互隔离,使它们成为线程安全的,而且您的测试将不那么冗长且更易于维护。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 2018-07-28
    • 1970-01-01
    • 1970-01-01
    • 2021-04-20
    • 2015-04-23
    • 1970-01-01
    相关资源
    最近更新 更多