【问题标题】:Moq: Mock SetUp method only returns null during testMoq:模拟 SetUp 方法仅在测试期间返回 null
【发布时间】:2016-01-14 18:10:47
【问题描述】:

我刚刚在我的应用程序中添加了依赖注入,并希望对我的方法运行模拟测试以确保它们正常工作。

我有一个域类 Person 具有以下属性:

public class Person : DomainBase
{
   public string FirstName { get; set; }
    public string LastName { get; set; }
    public char Gender { get; set; }
    public DateTime DOB {get; set; }
}

我有一个与其他域类型管理器共享的部分 manager 类:

public partial class Manager : IManager1
{
    private IHiveTiesContext _ctx; 
    public Manager(IHiveTiesContext context)
    {
        _ctx = context;
    }
}

接口IManager1是从我的PersonManager类中提取的,包含所有需要的方法。

我的 PersonManager CreatePerson() 方法正在被调用和测试:

public partial class Manager : IManager1
{
    public Person CreatePerson(string fn, string ln, DateTime dob, char gender, Guid RId)
    {
       var _person =_ctx.People.Add(new Person
       {  
          FirstName = fn,
          LastName = ln,
          DOB = dob,
          Gender = gender,
          RowId = RId});

          _ctx.SaveChanges();
          return _person;
        }
    }  
} 

我的上下文如下,我再次从中提取了一个接口IHiveTiesContext。

public class HiveTiesContext : DbContext, IHiveTiesContext
{
    public HiveTiesContext() :  base("hiveties")
    {
        Database.SetInitializer<HiveTiesContext>(null);
    }

    public virtual IDbSet<Person> People { get; set; }
}

最后我尝试像这样测试CreatePerson:

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>>();

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

        if(_person == null)
        {
            throw new Exception("NOT WORKING MAN!!!!");
        }

        var personid = mockContext.Object.People.Single(x => x.RowId == personGuid).Id;

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

我的问题是我的Person 对象从未被创建,也就是说,它总是返回一个null 值并且总是抛出异常。我相信我告诉它返回一个Person 实体,但我不确定我哪里出错了。这是我第一次使用Moq 并运行Mock Unit Tests。

感谢任何建议。谢谢。

【问题讨论】:

  • 您必须模拟设置 CreatePerson 方法。类似于 mockContent.Setup(m => m.CreatePerson(fn, ln, dob, gender, RId)).Returns(new Person){ //your object here });
  • 我会试试@Chris
  • 在创建 Person 对象后,请向下移动此代码部分 var manager = new Manager(mockContext.Object);。
  • 我无法在方法调用之后移动该代码,因为它需要先声明。 @克里斯
  • 哦,是的!我的错。为什么不创建一个在 IHiveTiesContext 中保存 Person 对象的函数?我将发布我的解决方案。

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


【解决方案1】:

您没有对mockDbSet 的Add 方法设置任何行为。

添加:(此行初始化返回给定人的方法)

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

模拟之间:

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 personid = mockContext.Object.People.Single(x =&gt; x.RowId == personGuid).Id;行创建的人那里得到一个ID personid返回为0,即使对象是创建,你知道为什么吗? @OldFox
  • @AaronLWG,这是因为mockContext.Object.People 是一个模拟对象...使用this answer 中的CreateMockSet 创建您的DbSet,然后将Callback 添加到我提供的设置中,在这个回调中,你会将给定的人放在列表中。
  • 说实话,这有点超出我的能力水平,所以我不是很明白。我希望找到一种从模拟的Person 对象中访问Id 属性的方法,但不太确定这是否会起作用@OldFox
【解决方案2】:

我在 IHiveTiesContext 中创建了一个新的签名/函数来保存 Person 对象。 (现在由您决定如何实现接口)。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SampleManager
{
    public class Manager : IManager
    {
        private IHiveTiesContext _ctx;
        public Manager(IHiveTiesContext context)
        {
            _ctx = context;
        }

        public Person CreatePerson(string fn, string ln, DateTime dob, char gender, Guid RId)
        {
            var person = _ctx.Save(fn, ln);
            return person;
        }
    }


    public class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public char Gender { get; set; }
        public DateTime DOB { get; set; }
        public Guid RowId { get; set; }
    }

    public interface IManager
    {
        Person CreatePerson(string fn, string ln, DateTime dob, char gender, Guid RId);
    }

    public interface IHiveTiesContext
    {
        Person Save(string fn, string ln);
    }
}

/// <summary>
    ///A test for CreatePerson
    ///</summary>
    [TestMethod()]
    public void CreatePersonTest1()
    {
        var mock = new Mock<IHiveTiesContext>();
        //fill up your expected object
        mock.Setup(m => m.Save(It.IsAny<string>(), It.IsAny<string>())).Returns(new Person { FirstName = "William" });

        Manager t = new Manager(mock.Object);
        var results = t.CreatePerson(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<DateTime>(), It.IsAny<Char>(), It.IsAny<Guid>());

        Assert.AreEqual("William", results.FirstName);
    }

【讨论】:

    猜你喜欢
    • 2010-12-19
    • 2021-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-30
    相关资源
    最近更新 更多