c#-4.0 - 单元测试代码契约(Contract)

标签 c#-4.0 nunit code-contracts

我只是在玩.Net 4.0中的代码契约,并且一定会遗漏一些明显的东西,因为它们的行为不像我期望的那样。

我一直使用简单的if ... then .. throw语句在函数开始时执行任何验证。

if (hours < 0 || hours > 8)
    throw new ArgumentOutOfRangeException("hours", "Hours must be between 0 and 8");

我已经简单地替换为
Contract.Requires<ArgumentOutOfRangeException>(hours >= 0 && hours <= 8, "Hours must be between 0 and 8");

但这似乎从未对我的单元测试造成任何问题。
    public static DurationUnit HoursAsDuration(int hours)
    {
        Contract.Requires<ArgumentOutOfRangeException>(hours >= 0 && hours <= 8, "Hours must be between 0 and 8");

        switch (hours)
        {
            case 1:
            case 2:
                return DurationUnit.Quarter;
            case 3:
            case 4:
                return DurationUnit.Half;
            case 5:
            case 6:
                return DurationUnit.ThreeQuarter;
            case 7:
            case 8:
                return DurationUnit.Full;
            default:
                return DurationUnit.None;
        }
    }

    [Test]
    public void CanConvertToDuration()
    {
        Assert.AreEqual(DurationUnit.None, DateTimeUtility.HoursAsDuration(0));
        Assert.AreEqual(DurationUnit.Quarter, DateTimeUtility.HoursAsDuration(1));
        Assert.AreEqual(DurationUnit.Quarter, DateTimeUtility.HoursAsDuration(2));
        Assert.AreEqual(DurationUnit.Half, DateTimeUtility.HoursAsDuration(3));
        Assert.AreEqual(DurationUnit.Half, DateTimeUtility.HoursAsDuration(4));
        Assert.AreEqual(DurationUnit.ThreeQuarter, DateTimeUtility.HoursAsDuration(5));
        Assert.AreEqual(DurationUnit.ThreeQuarter, DateTimeUtility.HoursAsDuration(6));
        Assert.AreEqual(DurationUnit.Full, DateTimeUtility.HoursAsDuration(7));
        Assert.AreEqual(DurationUnit.Full, DateTimeUtility.HoursAsDuration(8));

        //Would expect this to cause an issue
        Assert.AreEqual(DurationUnit.None, DateTimeUtility.HoursAsDuration(9));
    }

测试返回true,但是我希望代码协定停止将“9”的值输入到switch语句中。这是预期的行为吗?

最佳答案

如果您的函数规范以英语表示,则它接受hours的任何值并在hours不在0..8范围内时引发异常,则其契约(Contract)(以代码契约(Contract)语言表示)不是要求hours来执行。介于0到8之间。正确的翻译是该函数不需要任何内容​​,并且可以确保如果hours在错误的范围内,则引发异常,并且可以确保如果hours在正确的范围内,则正确的计算已完成。

我希望有一种方法可以在代码契约(Contract)中表达这些内容,但是我对这种契约(Contract)语言并不熟悉,只对另一种语言很熟悉。但是,其原理是相同的:如果您希望将支票包含在生产版本中,则支票的条件不是前提条件。另一方面,契约(Contract)可以(应该)表示已进行检查,并且每种情况都得到了适当的处理。

关于c#-4.0 - 单元测试代码契约(Contract),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5166006/

相关文章:

nunit - SpecFlow 错误地使用 NUnit

c# - 由契约(Contract)和 build 者设计

c# - 有没有一种方法可以编写代码契约来确保只有一种方法可以修改特定字段?

.net - 为什么.net 异常没有被捕获?

c# - Windows 应用程序的许可证 key 生成

.net - 如何在我们的测试项目上运行内存分析器?

c#-4.0 - 迭代时从字典中删除项目

c# - 如何每次在每个测试方法(包含在同一测试装置中)之前初始化实例变量(在 nunit 的测试装置中声明)?

tfs - 是否可以使用 TFS API 获取所有项目和子项目

c# - Nlog:如何将嵌套诊断上下文值输出到日志文件?