C#/xUnit异常测试时VS2017代码覆盖率未覆盖CompareTo代码块问题
Assert.Throws for VS2017 Code Coverage I’ve run into this exact issue with VS2017’s code coverage not tracking lambda invocations inside Assert.Throws before. The problem stems from how the coverage engine struggles to recognize code execution within anonymous lambdas passed directly to the assertion method. Here are a few practical fixes to get your f.CompareTo(b) call recognized as covered:
Solution 1: Use a Named Action Delegate
Assign the lambda to a named variable first. This makes the execution path more explicit for the coverage tool:
[Fact] public void NotImplementedComparison() { // Arrange var f = new Foo(); var b = new Bar(); Action compareAction = () => f.CompareTo(b); // Act var exception = Assert.Throws<NotImplementedException>(compareAction); // Assert Assert.Equal("Not implemented.", exception.Message); }
Solution 2: Extract the Call to a Separate Method
Moving the CompareTo call into a dedicated helper method ensures the coverage tool clearly sees the execution:
[Fact] public void NotImplementedComparison() { // Arrange var f = new Foo(); var b = new Bar(); // Act var exception = Assert.Throws<NotImplementedException>(() => ExecuteComparison(f, b)); // Assert Assert.Equal("Not implemented.", exception.Message); } private void ExecuteComparison(Foo f, Bar b) { f.CompareTo(b); // This line will now show as covered }
Solution 3: Manual Try-Catch (Verbose but Reliable)
If the above don’t work, replace Assert.Throws with a manual try-catch block. This removes any ambiguity about which lines are executed:
[Fact] public void NotImplementedComparison() { // Arrange var f = new Foo(); var b = new Bar(); NotImplementedException caughtException = null; // Act try { f.CompareTo(b); // Coverage will track this line } catch (NotImplementedException ex) { caughtException = ex; } // Assert Assert.NotNull(caughtException); Assert.Equal("Not implemented.", caughtException.Message); }
Why This Happens
VS2017’s code coverage engine has known quirks with tracking code inside anonymous lambdas passed directly to methods like Assert.Throws. By making the execution path more explicit, you help the tool recognize that the CompareTo call is indeed being executed during the test.
内容的提问来源于stack exchange,提问作者Dr. Strangelove

