Moq:如何检索模拟对象的 ID

Moq: How to retrieve ID of mocked object

我已经成功创建了一个模拟的 Person 对象,我现在正尝试使用我的 AddChild() 方法通过对象的 ID 添加一个子对象。我的测试看起来像这样:

public class PersonManagerMockTest
{
    private static Guid personGuid;

    [ClassInitialize]
    public static void Init(TestContext test)
    {
        personGuid = Guid.NewGuid();
    }

    [TestMethod]
    public void AddNewPerson()
    {
        //Arrange
        var mockDbSet = new Mock<DbSet<Person>>();
        mockDbSet.Setup(x => x.Add(It.IsAny<Person>()))
            .Returns<Person>(p => p);

        var mockContext = new Mock<IHiveTiesContext>();
        mockContext.Setup(x => x.People)
            .Returns(mockDbSet.Object);
        var manager = new Manager(mockContext.Object);

        //Assert
        var _person = manager.CreatePerson("Winston", "Gabriel", DateTime.Now, 'M', personGuid);

        var fatherid = mockDbSet.Object.SingleOrDefault(x => x.RowId == personGuid).Id;
        manager.AddChild(new Person
        {
            FirstName = "Aaron",
            LastName = "Gabriel",
            DOB = new DateTime(1991, 01, 16),
            FavoriteColor = "Red",
            FatherId = fatherid,
        });

        //Act
        mockDbSet.Verify(x => x.Add(It.IsAny<Person>()), Times.Once);
        mockContext.Verify(x => x.SaveChanges(), Times.Once);
    }
}

模拟的Person对象创建成功,但是问题出在这条语句:

var fatherid = mockDbSet.Object.SingleOrDefault(x => x.RowId == personGuid).Id;

我不确定如何从模拟的 Person 对象中检索 Id,并且我认为此语句为 fatherid 返回了 0,这意味着它是null。这是我第一次 运行 模拟,所以我还在学习中。关于如何从这个模拟的 Person 对象中检索 Id 的任何建议? 我将不胜感激所有建议。谢谢。

MockObjects 没有逻辑,无法生成 Id。

由于 DbSet 是模拟的,所以您必须告诉它应该做什么。所以尝试像这样更改 DbSet 的设置:

var newId = 42;
var mockDbSet = new Mock<DbSet<Person>>();
mockDbSet.Setup(x => x.Add(It.IsAny<Person>()))
         .Returns(newId);

通过这种方式,您告诉 Moq,当有人呼叫 DbSet.Add 时,无论是什么人,都必须 return 42.

我使用了 this answer 中的 CreateMockSet 方法。

变化:

var mockDbSet = new Mock<DbSet<Person>>();
mockDbSet.Setup(x => x.Add(It.IsAny<Person>()))
         .Returns<Person>(p => p);

收件人:

var persons = new List<Person>();

var mockDbSet = CreateMockSet(persons.AsQueryable());
mockDbSet.Setup(x => x.Add(It.IsAny<Person>()))
         .Callback<Person>(persons.Add)
         .Returns <Person>(p => p);

Callback 方法使用新的 Person 实例填充 persons 列表。

CreateMockSet() 使用 persons 的 return 设置创建 Mock<DbSet<Person>>(在 mockDbSet.Object

让OldFoxes对先天的回答更清楚!

 mockSet.Setup(x => x.Add(It.IsAny<ValuationCompany>()))
                .Callback<ValuationCompany>(data.Add)
                .Returns<ValuationCompany>(p =>
                {
                    p.Id = 23;  // Assign whatever you want here.
                    return p;
                });