【问题标题】:How to save a value to return it later?如何保存一个值以便以后返回?
【发布时间】:2014-01-01 00:01:54
【问题描述】:

我有一个接口ILogger,它有一个LocalTime 属性,可以用AddToTime 向它添加时间。为了适当地模拟它,我尝试了以下方法:

int ltime = 0;
var mlog = new Mock<ILogger>();
mlog.Setup(l => l.AddToTime(It.IsAny<int>())).Callback((int s) => {ltime +=s;});
mlog.Setup(l => l.LocalTime).Returns(ltime);

虽然它可以编译,但 i 不起作用:可能是因为 Returns 在开头计算表达式 ltime,所以总是返回 0。有什么建议可以实现缩进的行为吗?

编辑:我需要这个来测试它,如下所示:

while (log.LocalTime < 1000)
        {
            log.AddToTime(500);
             ....
         }

由于我将时间用于记录目的,因此不能简单地用带有局部变量的循环替换它。如果AddToTime 什么都不做,则无法正确测试循环。

【问题讨论】:

  • 为什么不把它做成存根呢?我不记得有关如何在 Moq 中设置存根的正确文档,但我知道您可以做到。您尝试过这种方法吗?
  • 那么,您在 SUT 中硬编码了 1000 和 500?你能描述一下这个代码的要求吗?也可以修改Logger吗?
  • 您没有发布其余的测试方法。
  • 我的代码中没有硬编码 1000 和 500(这是一个示例……)。我只想以这种循环执行一次但不是无限频繁的方式模拟 ILogger。
  • @JFMeier 测试是编码要求。为了帮助您编写测试,我们确实需要了解需求

标签: c# return moq


【解决方案1】:

您可以使用Returns 方法代替Callback
这里的例子: Settings variable values in a Moq Callback() call

【讨论】:

    【解决方案2】:

    这是一个测试,我建议你在测试中避免任何逻辑。只有你应该有一些逻辑的地方是你正在测试的 SUT。否则,模拟记录器的实现会潜入其他类的测试中。只需设置您期望的值:

    int ltime = 0;
    int timeToAdd = 2;
    var mlog = new Mock<ILogger>();
    mlog.Setup(l => l.AddToTime(timeToAdd));
    mlog.Setup(l => l.LocalTime).Returns(ltime + timeToAdd);
    

    我什至会尝试避免最后一次返回设置计算并将其替换为恒定的预期值。但我需要更多地了解您正在测试的逻辑。

    【讨论】:

    • 该接口用于循环,达到时间限制后退出。因此,设置常量值会导致无限循环或根本不调用。或者,我需要在第一次调用时返回低 LocalTime 的东西,并在任何进一步调用时返回高值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-16
    • 1970-01-01
    • 2021-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多