Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在NUnit中编写需要括号的fluent约束_C#_Unit Testing_Nunit_Fluent Interface - Fatal编程技术网

C# 如何在NUnit中编写需要括号的fluent约束

C# 如何在NUnit中编写需要括号的fluent约束,c#,unit-testing,nunit,fluent-interface,C#,Unit Testing,Nunit,Fluent Interface,我最近开始使用NUnit的约束功能,遇到了以下问题。在执行顺序很重要的情况下,如何使用fluent表达式语法编写约束,而在普通C#编程中,约束是用括号解决的 在下面的示例中,我定义了两个独立的断言: 字符串应以1或2开头,在所有情况下,字符串均应以5结尾 字符串应以1或2开头,如果字符串以2开头,则应以5结尾 要坚持这一点,我可以考虑三种方式;经典、流畅的约束和使用复合约束的约束。这将导致6个测试和一些测试用例 private class SourceForParenthesisTest : I

我最近开始使用NUnit的约束功能,遇到了以下问题。在执行顺序很重要的情况下,如何使用fluent表达式语法编写约束,而在普通C#编程中,约束是用括号解决的

在下面的示例中,我定义了两个独立的断言:

  • 字符串应以1或2开头,在所有情况下,字符串均应以5结尾
  • 字符串应以1或2开头,如果字符串以2开头,则应以5结尾
  • 要坚持这一点,我可以考虑三种方式;经典、流畅的约束和使用复合约束的约束。这将导致6个测试和一些测试用例

    private class SourceForParenthesisTest : IEnumerable
    {
        public IEnumerator GetEnumerator()
        {
            yield return new TestCaseData("2").Throws(typeof(AssertionException));
            yield return new TestCaseData("3").Throws(typeof(AssertionException));
            yield return new TestCaseData("15");
            yield return new TestCaseData("25");
            yield return new TestCaseData("35").Throws(typeof(AssertionException));
        }
    }
    
    [TestCase("1", ExpectedException = typeof(AssertionException))]
    [TestCaseSource(typeof(SourceForParenthesisTest))]
    public void WithParenthesisClassic(string i)
    {
        var res = (i.StartsWith("1") || i.StartsWith("2")) && i.EndsWith("5");
        Assert.True(res);
    }
    
    [TestCase("1", ExpectedException = typeof(AssertionException))]
    [TestCaseSource(typeof(SourceForParenthesisTest))]
    public void WithParenthesisOperatorConstraint(string i)
    {
        Assert.That(i, (Is.StringStarting("1") | Is.StringStarting("2")) & Is.StringEnding("5"));
    }
    
    [TestCase("1", ExpectedException = typeof(AssertionException), Ignore = true, IgnoreReason = "Not clear how to write this fluent expression")]
    [TestCaseSource(typeof(SourceForParenthesisTest))]
    public void WithParenthesisConstraint(string i)
    {
        Assert.That(i, Is.StringStarting("1").Or.StringStarting("2").And.StringEnding("5"));
    }
    
    [TestCase("1")]
    [TestCaseSource(typeof(SourceForParenthesisTest))]
    public void NoParenthesisClassic(string i)
    {
        var res = i.StartsWith("1") || i.StartsWith("2") && i.EndsWith("5");
        Assert.True(res);
    }
    
    [TestCase("1")]
    [TestCaseSource(typeof(SourceForParenthesisTest))]
    public void NoParenthesisOperatorConstraint(string i)
    {
        Assert.That(i, Is.StringStarting("1") | Is.StringStarting("2") & Is.StringEnding("5"));
    }
    
    [TestCase("1")]
    [TestCaseSource(typeof(SourceForParenthesisTest))]
    public void NoParenthesisConstraint(string i)
    {
        Assert.That(i, Is.StringStarting("1").Or.StringStarting("2").And.StringEnding("5"));
    }
    
    实际的问题是WithBranchisConstraint(上面列出的Assert1),我无法思考如何正确编写约束,这导致了一个失败的测试用例,我已将其设置为忽略


    如何编写此断言以使其按预期工作

    我也看不出一个明显的方法来做到这一点。我的第一个想法是,您需要将表达式解析到一个给定的点,这使得您的断言如下所示:

    Assert.That(i, ((IResolveConstraint)Is.StringStarting("1").Or.StringStarting("2"))
                                          .Resolve().With.StringEnding("5"))
    
    public static ConstraintExpression OnlyIf(this Constraint exp) {
        return ((IResolveConstraint)exp).Resolve().And;
    }
    
    Assert.That(i, (Is.StringStarting("1").Or.StringStarting("2")).OnlyIf()
                                                                  .StringEnding("5")); 
    
    这显然有点乱。您可以添加自己的扩展方法,使其更令人愉快,使用类似的方法(显然,您可以将扩展方法重命名为任何您认为合适的方法):

    这将使您的测试代码断言:

    Assert.That(i, (Is.StringStarting("1").Or.StringStarting("2")).Evaluate()
                                          .And.StringEnding("5"));
    
    这是一个有点好,但不是理想的,所以可能不是你想要的

    还值得考虑将
    Evaluate
    约束结合起来,以便于阅读。可能是这样一种扩展方法:

    Assert.That(i, ((IResolveConstraint)Is.StringStarting("1").Or.StringStarting("2"))
                                          .Resolve().With.StringEnding("5"))
    
    public static ConstraintExpression OnlyIf(this Constraint exp) {
        return ((IResolveConstraint)exp).Resolve().And;
    }
    
    Assert.That(i, (Is.StringStarting("1").Or.StringStarting("2")).OnlyIf()
                                                                  .StringEnding("5")); 
    
    要给出这样的测试代码:

    Assert.That(i, ((IResolveConstraint)Is.StringStarting("1").Or.StringStarting("2"))
                                          .Resolve().With.StringEnding("5"))
    
    public static ConstraintExpression OnlyIf(this Constraint exp) {
        return ((IResolveConstraint)exp).Resolve().And;
    }
    
    Assert.That(i, (Is.StringStarting("1").Or.StringStarting("2")).OnlyIf()
                                                                  .StringEnding("5"));