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

时间:2016-01-14 20:26:27

标签: c# unit-testing mocking entity-framework-6 moq

我已经成功创建了一个模拟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;

我不确定如何从模拟的Id对象中检索Person,因为我认为此语句为0返回fatherid,意味着它是{{} 1}}。这是我第一次跑嘲笑,所以我还在学习。有关如何从此模拟的null对象中检索Id的任何建议吗? 我将感谢所有的建议。谢谢。

3 个答案:

答案 0 :(得分:2)

我使用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方法使用新的persons实例填充Person列表。

CreateMockSet()创建Mock<DbSet<Person>>,返回设置为persons(在mockDbSet.Object上)

答案 1 :(得分:2)

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

答案 2 :(得分:0)

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无论是什么人,它都必须返回42。