Fluent断言:断言一个或另一个值

时间:2014-08-28 06:31:25

标签: c# unit-testing combinations assert fluent-assertions

使用流畅的断言,我想声明给定的字符串包含两个字符串之一:

actual.Should().Contain("oneWay").Or().Should().Contain("anotherWay"); 
// eiter value should pass the assertion.
// for example: "you may do it oneWay." should pass, but
// "you may do it thisWay." should not pass

仅当包含这两个值时,断言才会失败。这不起作用(甚至不编译),因为没有Or()运算符。

我现在就是这样做的:

bool isVariant1 = actual.Contains(@"oneWay");
bool isVariant2 = actual.Contains(@"anotherWay");
bool anyVariant = (isVariant1 || isVariant2);
anyVariant.Should().BeTrue("because blahblah. Actual content was: " + actual);

这是冗长的,"因为"必须手动创建参数以获得有意义的输出。

有没有办法以更易读的方式执行此操作?解决方案也应该适用于其他流畅的断言类型,例如Be()HaveCount()等...

如果重要的话,我在.NET 3.5上使用FluentAssertions 2.2.0.0版。

3 个答案:

答案 0 :(得分:11)

我会把它作为字符串断言的扩展。像这样:

public static void BeAnyOf(this StringAssertions assertions, string[] expectations, string because, params string[] args) {
    Execute.Assertion
           .ForCondition(expectations.Any(assertions.Subject.Contains))
           .BecauseOf(because, args)
           .FailWith("Expected {context:string} to be any of {0}{reason}", expectations);
}

您甚至可以分叉repository并向我提供Pull Request以使其成为下一个版本的一部分。

答案 1 :(得分:9)

不应该这样吗?

actual.Should().BeOneOf("oneWay", "anotherWay");

使用v3.1.229为我工作。

答案 2 :(得分:1)

通过编写简单的字符串扩展名,您可以使其更具可读性:

public static class StringExt
{
    public static bool ContainsAnyOf(this string self, params string[] strings)
    {
        return strings.Any(self.Contains);
    }
}

然后你可以这样做:

actual.ContainsAnyOf("oneWay", "anotherWay").Should().BeTrue("because of this reason");

不幸的是,这对"原因"没有帮助。消息的一部分,但我认为它好一点。