【问题标题】:Have setup MOQ with methods, but it does not throw exception when passed null argument已使用方法设置 MOQ,但在传递空参数时不会抛出异常
【发布时间】:2017-10-19 01:12:38
【问题描述】:

我有一个测试类并使用测试方法对其进行初始化。我还设置了带有模拟数据的方法返回。但是,当我传递像 null 这样的无效参数时,我应该返回一个 null 异常,就像在我的类中实现的那样。

相反,我得到 0 个结果,而不是空异常。

[TestInitialize]
        public void Initialize()
        {
            _mySSystemHealthRepo= new Mock<ImySSystemHealthRepo>();
            //Arrannge



            List<JobHistory> allJobHistory = new List<JobHistory>
            {
                new JobHistory
                {
                    Id = 2,
                    StartTime = DateTime.Parse("15 OCT 2017"),
                    EndTime = DateTime.Parse("18 OCT 2017"),
                   Engineer = techhelpn@myhs-gus.com"
                    Name="Job1"
                }
                ,

                new JobHistory
                {
                    Id = 3,
                    StartTime = DateTime.Parse("12 OCT 2017"),
                    EndTime = DateTime.Parse("14 OCT 2017"),
                  Engineer = "sales@myhs-gus.com"
                    Name="Job1"
                },

                new JobHistory
                {
                     Id = 4,
                     StartTime = DateTime.Parse("11 OCT 2017"),
                     EndTime = DateTime.Parse("16 OCT 2017"),
                      Engineer = "supports@myhs-gus.com"
                     Name="Job1"
                }

            };

            _ziSystemHealthRepo.Setup(obj => obj.GetJobHistoryByName(DateTime.Parse("01 OCT 2017"),  DateTime.Parse("30 OCT 2017"), "TestJob")).Returns(allJobHistory);
        }


 [TestMethod]
 [ExpectedException(typeof(ArgumentNullException))]
       public void Repo_GetJobHistoryByNames_PassAllNull_ArgumenNullException()
            {
                ImySSystemHealthRepo repo = _mySSystemHealthRepo.Object;

                //Act
                var allJobs = repo.GetJobHistoryByName(default(DateTime), default(DateTime), null);

                //Assert

            }

我的实际实现是这样的。

 public IEnumerable<JobHistory> GetJobHistoryByName(DateTime startDate, DateTime endDate,string jobName)
        {

            if (String.IsNullOrEmpty(jobName))
            {
                throw new ArgumentNullException("jobName");
            }

            var jobDetails = _context.JobHistories.Where(jh => jh.StartTime >= startDate && jh.EndTime <= endDate);

            jobDetails = jobDetails.Where(jh=>jh.Name == jobName);

            return jobDetails;
        }

编辑:

如果我不使用 MOQ 并将上下文作为 null 传递,则以下方法将失败。

[TestMethod]
    public void Repo_GetJobHistoryByNames_PassValid_GetAllRecordsBack()
    {

        mySYSSystemHealthRepo repo = new mySYSSystemHealthRepo(null);

        //Act
        var allJobs = repo.GetJobHistoryByName(DateTime.Parse("01 OCT 2017"), DateTime.Parse("30 OCT 2017"), "TestJob");
        var allEngineers = allJobs.Select(x => x.Engineer);

        //Assert
        Assert.AreEqual(3, allJobs.Count());
        Assert.IsTrue(allEngineers.Contains("supp"));

    }

【问题讨论】:

  • 当前状态的问题不清楚,因为它不完整。阅读How to Ask,然后提供minimal reproducible example,可以用来更好地理解您的问题。
  • 另外你为什么要嘲笑被测对象?目标通常是模拟被测对象的依赖关系。
  • 创建一个被测对象的实例。注入上下文并调用被测的实际方法。根据显示的方法,空测试应该可以工作
  • 当我注入上下文时,应该是实际上下文还是模拟上下文?如果我要注入实际的上下文,那么我是否依赖于外部来源?只是想把它做好。
  • 如果要使用上下文,可以模拟它。如果将其作为 null 注入测试没有连锁反应,则只需传递 null。

标签: c# .net asp.net-mvc unit-testing moq


【解决方案1】:

创建一个被测对象的实例。注入模拟的上下文和任何其他依赖项,然后调用被测的实际方法。根据显示的方法,空测试应该可以工作

[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void Repo_GetJobHistoryByNames_PassAllNull_ArgumenNullException() {
    //Arrange
    ImySSystemHealthRepo repo = new MyActualSystemHealthRepo(context: null);

    //Act
    var allJobs = repo.GetJobHistoryByName(default(DateTime), default(DateTime), null);

    //Assert
    //...N/A
}

在第二个测试用例中,需要模拟上下文依赖以返回假数据,然后注入到被测对象中。

[TestMethod]
public void Repo_GetJobHistoryByNames_PassValid_GetAllRecordsBack() {
    //Arrange
    var mockContext = new Mock<IMyContext>();
    mockContext.Setup(_ => _.JobHistories).Returns(allJobHistory);

    var repo = new mySYSSystemHealthRepo(mockContext.Object);

    //Act
    var allJobs = repo.GetJobHistoryByName(DateTime.Parse("01 OCT 2017"), DateTime.Parse("30 OCT 2017"), "TestJob");
    var allEngineers = allJobs.Select(x => x.Engineer);

    //Assert
    Assert.AreEqual(3, allJobs.Count());
    Assert.IsTrue(allEngineers.Contains("supp"));
}

调用时上下文将返回假集合,linq 表达式应枚举它。

【讨论】:

  • 这适用于当前问题,因为我在使用上下文之前抛出空异常。其他使用上下文的方法怎么样(在 Edit 上发布了一个示例)?我怎样才能一个 MoQ 上下文而不是 null 或我的实际上下文?抱歉,如果我问的问题太多。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-28
  • 2015-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多