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

Why my expected and actual results are same but test fails?

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

这是我的测试Class:

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 测试结果的图片。 这是我的错误:

oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo

原因是对象不是通过其属性值进行比较,而是通过引用进行比较。

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

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

这可能是我在这种特殊情况下会采用的方法,因为您的 ValidationResult class 很简单,您可能不会在整个代码库中测试它是否相等。这还具有独立断言消息和结果的优点,因此您的测试可以告诉您是否意外分配了一条对传递的 ValidationResult 没有意义的消息。

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

还有一个适用于更复杂场景的选项 IEquatable,它允许您实施自己的方法来测试相等性。不过我不会为你的情况而烦恼。