【问题标题】:Why my expected and actual results are same but test fails?为什么我的预期和实际结果相同,但测试失败?
【发布时间】:2021-07-03 10:55:36
【问题描述】:

为什么我的预期和实际结果相同,但测试失败?

这是我的测试课:

private readonly Mock<IMongoDbContext> _moqIMongoDbContext;
    private readonly JobStore _jobStore;

    public JobStoreTest()
    {
        _moqIMongoDbContext = new Mock<IMongoDbContext>();
        _jobStore = new JobStore(_moqIMongoDbContext.Object, new Validator.Validator());

        _moqIMongoDbContext
            .Setup(_ => _.Jobs.InsertOneAsync(
                It.IsAny<Job>(),
                It.IsAny<InsertOneOptions>(),
                It.IsAny<CancellationToken>())
            )
            .Returns((Job y, InsertOneOptions options, CancellationToken token)
                => Task.FromResult(y));

    }

    

    [Theory]
    [ClassData(typeof(JobClassesForTesting))]
    public async Task CreateAsync(IJob job, ValidationResult expectedValidationResult)
    {

        //Act
        ValidationResult validationResult = await _jobStore.ValidateCreateAsync(job);

        //Assert
        Assert.Equal(expectedValidationResult, validationResult);
    }

这是我的场景(JobClassesForTesting):

   public class JobClassesForTesting : IEnumerable<object[]>
{
    public IEnumerator<object[]> GetEnumerator()
    {
        var valid = new ValidationResult()
        {
            ValidationResultEnum = ValidationResultEnum.Valid,
            ValidationResultMessageEnum = ValidationResultMessageEnum.NotNullFound
        };

        var invalid = new ValidationResult()
        {
            ValidationResultEnum = ValidationResultEnum.Invalid,
            ValidationResultMessageEnum = ValidationResultMessageEnum.NullProperty
        };

        yield return new object[] {
            new Job() {
                Payload = null,
                EntityName = "EntityNameTest1",
                Module = "ModuleTest1",
            },
            invalid
        };

        yield return new object[] {
            new Job() {
                Payload = "PayloadTest2",
                EntityName = "EntityNameTest2",
                Module = "ModuleTest2",
            },
            valid
        };

        yield return new object[] {
            new Job() {
                Payload = "PayloadTest3",
                EntityName = "EntityNameTest3",
                Module = "ModuleTest3",
            },
            valid
        };
    }

    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}

虽然我的实际结果和预期结果相同,但测试失败。 我在下面添加了一张 xUnit 测试结果的图片。 这是我的错误:

ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo

【问题讨论】:

  • 这不是数组的比较方式。数组相等性测试它是否是完全相同的数组,而不是内容是否完全相同的形状。您想比较数组中对象的值,因此您需要为您的 Job 对象使用自定义比较器,或者遍历 Job 并比较这些值。
  • @maembe 我想检查 Job 的属性之一是否为空
  • ValidationResult 是你写的吗?如果是这样,是class 还是struct
  • 是的,我写了,这是一门课@JoshuaRobinson

标签: c# unit-testing asp.net-core xunit


【解决方案1】:

这样做的原因是对象不是通过其属性的值而是通过它们的引用进行比较的。

对此的快速解决方法是比较验证结果的每个属性:

Assert.Equal(expectedValidationResult.ValidationResultEnum , validationResult.ValidationResultEnum );
Assert.Equal(expectedValidationResult.ValidationResultMessageEnum , validationResult.ValidationResultMessageEnum );

这可能是我在这种特殊情况下要走的路线,因为您的 ValidationResult 类很简单,而且您可能不会在整个代码库中测试它是否相等。这还具有独立断言您的消息和结果的优势,因此您的测试可以告诉您是否意外分配了一条对于通过的 ValidationResult 没有意义的消息。

c# 9 中的另一个选项是record types,它按值而不是按引用进行比较。对于只是数据块的对象,例如 ValidationResult 对象,这是一个不错的选择。

对于更复杂的场景还有另一个选项IEquatable,它允许您实现自己的方法来测试相等性。不过,在你的情况下,我不会打扰它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-07
    • 1970-01-01
    • 1970-01-01
    • 2021-07-29
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    相关资源
    最近更新 更多