【问题标题】:Assert Statement for ternary operator in Rhino mocks? [closed]在 Rhino 模拟中为三元运算符断言声明? [关闭]
【发布时间】:2023-10-29 05:36:01
【问题描述】:
x(string)= y(string) != ? y : string.empty

如何使用 Assert 语句获得 100% 的代码覆盖率

我们尝试过使用: Assert.AreEqual(Actualvalue,ExpectedValue); 但我们在某处缺少代码覆盖率

【问题讨论】:

  • 能否添加真实代码?您提供的代码甚至无法编译!此外,100% 的代码覆盖率不应该只是一个目标。您需要测试哪些用例和/或要求?
  • 很抱歉,出于合规性问题,我们无法提供真实代码,但我们只想知道如何在代码覆盖范围内使用断言语句覆盖三元运算符。此外,根据我们的用例,我们必须将其覆盖在代码覆盖范围内。
  • 基本上,您需要两个测试用例来实现 100% 的覆盖率,一个用于条件 y != ... 通过,一个用于失败。但是,根据这种情况,您可能需要添加更多案例。因此,要么实现两个测试方法,要么创建一个并应用 TestCase-attribute 和 Result-param。
  • @HimBromBeere 我们已经尝试了 2 个测试用例,但它并没有覆盖整个生产线。你能详细说明你的替代解决方案吗?

标签: c# code-coverage rhino-mocks


【解决方案1】:

如果这就是你所做的一切,你真的不应该以 100% 的代码覆盖率为目标。没有正确测试任何东西的单元测试是浪费时间和可维护性。

为了全面测试(100%)三元运算符,您需要测试所有条件。

考虑一个简单的布尔变量“isMorning”,当 true 返回“Morning”而 false 返回“Afternoon”时。您需要编写一个将“isMorning”设置为“true”的测试,因此预期结果为“Morning”,然后将另一个“isMorning”设置为“false”的测试,因此预期结果为“Afternoon”。

public void Test1() {
  var isMorning = true;
  var result = isMorning ? "Morning" : "Afternoon";
  Assert.AreEqual("Morning", result);
}

public void Test2() {
  var isMorning = false;
  var result = isMorning ? "Morning" : "Afternoon";
  Assert.AreEqual("Afternoon", result);
}

希望这会有所帮助。

仅供参考 - 如果您使用 JetBrains DOTCOVER 之类的工具,它会突出显示未测试的代码。

【讨论】:

    【解决方案2】:

    基本上,如果您的整个代码只是x = y != ... y : string.empty,您需要两个不同的测试用例,一个用于条件通过,一个用于条件失败。

    这可以通过两种方式实现。一种是为每个案例创建一个测试方法:

    string MethodToTest(string y) {
        return y != /* whatever your condition is */ ? y : string.empty
    }
    [Test]
    public void Test1() {
        Assert.AreEqual(MethodToTest("PassingCondition"), "PassingCondition");
    }
    [Test]
    public void Test2() {
        Assert.AreEqual(MethodToTest("NotPassingCondition"), string.empty);
    }
    

    另一种方法是创建一个方法并将TestCase-attribute 添加到它:

    [TestCase("PassingCondition", Result = "PassingCondition")]
    [TestCase("NotPassingCondition", Result = string.empty)]
    public bool TheTest(string y) {
        return MethodToTest(y);
    }
    

    但是,两种方法在代码覆盖率方面是相同的。这取决于您如何实现代码覆盖的实际情况。但是您没有提供实际情况,因此我们无法回答该具体问题。

    编辑:由于您还提供了 Rhino-mocks(我不熟悉),我假设您传递的条件是由您要模拟的方法返回的。因此,一旦返回一个通过条件和一个返回失败条件,就模拟这个方法。

    【讨论】:

    • 其实我们是用Rhino Mock来测试的,你在样例中使用的属性是Nunit的。相反,我们使用了您在第一种方法中提供的相同过程,但我们仍然无法获得完整的代码覆盖率
    • 我不知道 rhino 是否知道[TestCase]-attribute,但是您仍然可以使用[TestMethod] 而不是[Test] 的第一种方法。
    • 仅供参考 - Rhino Mocks 用于模拟,而不是用于测试属性。 NUnit、XUnit、MSTest 等都包含测试属性,如 TestCase、Test 等……尽管根据您使用的不同而有所不同。以下是测试框架的比较:xunit.github.io/docs/comparisons.html
    • @ShaneYu 我已经假设了,但是我不确定它是否也支持测试属性。但是感谢您的澄清
    • @HimBromBeere 那么您使用的是什么测试框架? MSTest、Xunit、NUnit 还是其他?