Modify S3431: Promote C# rule to SonarWay (#4127)
This commit is contained in:
parent
8f7fcf7047
commit
716a7aa85d
33
rules/S3431/csharp/flow-example.adoc
Normal file
33
rules/S3431/csharp/flow-example.adoc
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
[source,csharp]
|
||||||
|
----
|
||||||
|
[TestMethod]
|
||||||
|
[ExpectedException(typeof(InvalidOperationException))]
|
||||||
|
public void UsingTest()
|
||||||
|
{
|
||||||
|
Console.ForegroundColor = ConsoleColor.Black;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var _ = new ConsoleAlert();
|
||||||
|
Assert.AreEqual(ConsoleColor.Red, Console.ForegroundColor);
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Assert.AreEqual(ConsoleColor.Black, Console.ForegroundColor); // The exception itself is not relevant for the test.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class ConsoleAlert : IDisposable
|
||||||
|
{
|
||||||
|
private readonly ConsoleColor previous;
|
||||||
|
|
||||||
|
public ConsoleAlert()
|
||||||
|
{
|
||||||
|
previous = Console.ForegroundColor;
|
||||||
|
Console.ForegroundColor = ConsoleColor.Red;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose() =>
|
||||||
|
Console.ForegroundColor = previous;
|
||||||
|
}
|
||||||
|
----
|
30
rules/S3431/csharp/how-mstest.adoc
Normal file
30
rules/S3431/csharp/how-mstest.adoc
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
== How to fix it in MSTest
|
||||||
|
|
||||||
|
Remove the `ExpectedException` attribute in favor of using the https://learn.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.testtools.unittesting.assert.throwsexception[Assert.ThrowsException] assertion.
|
||||||
|
|
||||||
|
=== Code examples
|
||||||
|
|
||||||
|
==== Noncompliant code example
|
||||||
|
|
||||||
|
[source,csharp,diff-id=1,diff-type=noncompliant]
|
||||||
|
----
|
||||||
|
[TestMethod]
|
||||||
|
[ExpectedException(typeof(ArgumentNullException))] // Noncompliant
|
||||||
|
public void Method_NullParam()
|
||||||
|
{
|
||||||
|
var sut = new MyService();
|
||||||
|
sut.Method(null);
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
|
==== Compliant solution
|
||||||
|
|
||||||
|
[source,csharp,diff-id=1,diff-type=compliant]
|
||||||
|
----
|
||||||
|
[TestMethod]
|
||||||
|
public void Method_NullParam()
|
||||||
|
{
|
||||||
|
var sut = new MyService();
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => sut.Method(null));
|
||||||
|
}
|
||||||
|
----
|
30
rules/S3431/csharp/how-nunit.adoc
Normal file
30
rules/S3431/csharp/how-nunit.adoc
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
== How to fix it in NUnit
|
||||||
|
|
||||||
|
Remove the `ExpectedException` attribute in favor of using the https://docs.nunit.org/articles/nunit/writing-tests/assertions/classic-assertions/Assert.Throws.html[Assert.Throws] assertion.
|
||||||
|
|
||||||
|
=== Code examples
|
||||||
|
|
||||||
|
==== Noncompliant code example
|
||||||
|
|
||||||
|
[source,csharp,diff-id=2,diff-type=noncompliant]
|
||||||
|
----
|
||||||
|
[Test]
|
||||||
|
[ExpectedException(typeof(ArgumentNullException))] // Noncompliant
|
||||||
|
public void Method_NullParam()
|
||||||
|
{
|
||||||
|
var sut = new MyService();
|
||||||
|
sut.Method(null);
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
|
==== Compliant solution
|
||||||
|
|
||||||
|
[source,csharp,diff-id=2,diff-type=compliant]
|
||||||
|
----
|
||||||
|
[Test]
|
||||||
|
public void Method_NullParam()
|
||||||
|
{
|
||||||
|
var sut = new MyService();
|
||||||
|
Assert.Throws<ArgumentNullException>(() => sut.Method(null));
|
||||||
|
}
|
||||||
|
----
|
@ -1,52 +1,18 @@
|
|||||||
|
include::../../../shared_content/dotnet/csharp_dictionary.adoc[]
|
||||||
|
:language: csharp
|
||||||
|
|
||||||
== Why is this an issue?
|
== Why is this an issue?
|
||||||
|
|
||||||
include::../description.adoc[]
|
include::../description.adoc[]
|
||||||
|
|
||||||
=== Noncompliant code example
|
|
||||||
|
|
||||||
[source,csharp]
|
|
||||||
----
|
|
||||||
[TestMethod]
|
|
||||||
[ExpectedException(typeof(ArgumentNullException))] // Noncompliant
|
|
||||||
public void TestNullArg()
|
|
||||||
{
|
|
||||||
//...
|
|
||||||
}
|
|
||||||
----
|
|
||||||
|
|
||||||
=== Compliant solution
|
|
||||||
|
|
||||||
[source,csharp]
|
|
||||||
----
|
|
||||||
[TestMethod]
|
|
||||||
public void TestNullArg()
|
|
||||||
{
|
|
||||||
bool callFailed = false;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
//...
|
|
||||||
}
|
|
||||||
catch (ArgumentNullException)
|
|
||||||
{
|
|
||||||
callFailed = true;
|
|
||||||
}
|
|
||||||
Assert.IsTrue(callFailed, "Expected call to MyMethod to fail with ArgumentNullException");
|
|
||||||
}
|
|
||||||
----
|
|
||||||
|
|
||||||
or
|
|
||||||
|
|
||||||
[source,csharp]
|
|
||||||
----
|
|
||||||
[TestMethod]
|
|
||||||
public void TestNullArg()
|
|
||||||
{
|
|
||||||
Assert.ThrowsException<ArgumentNullException>(() => /*...*/);
|
|
||||||
}
|
|
||||||
----
|
|
||||||
|
|
||||||
include::../exceptions.adoc[]
|
include::../exceptions.adoc[]
|
||||||
|
|
||||||
|
include::./how-mstest.adoc[]
|
||||||
|
|
||||||
|
include::./how-nunit.adoc[]
|
||||||
|
|
||||||
|
include::../resources.adoc[]
|
||||||
|
|
||||||
ifdef::env-github,rspecator-view[]
|
ifdef::env-github,rspecator-view[]
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
It should be clear to a casual reader what code a test is testing and what results are expected. Unfortunately, that's not usually the case with the `ExpectedException` attribute since an exception could be thrown from almost any line in the method.
|
It should be clear to a casual reader what code a test is testing and what results are expected. Unfortunately, that's not usually the case with the `ExpectedException` attribute since an exception could be thrown from almost any line in the method.
|
||||||
|
|
||||||
This rule detects MSTest and NUnit `ExpectedException` attribute.
|
This rule detects MSTest and NUnit `ExpectedException` attribute.
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
=== Exceptions
|
=== Exceptions
|
||||||
|
|
||||||
This rule ignores one-line test methods, since it is obvious in such methods where the exception is expected to be thrown.
|
This rule ignores:
|
||||||
|
|
||||||
|
* single-line tests, since it is obvious in such methods where the exception is expected to be thrown
|
||||||
|
* tests when it tests control flow and assertion are present in either a `{keyword_catch}` or `{keyword_finally}` clause
|
||||||
|
|
||||||
|
include::{language}/flow-example.adoc[]
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
"sqKey": "S3431",
|
"sqKey": "S3431",
|
||||||
"scope": "Tests",
|
"scope": "Tests",
|
||||||
"defaultQualityProfiles": [
|
"defaultQualityProfiles": [
|
||||||
|
"Sonar way"
|
||||||
],
|
],
|
||||||
"quickfix": "unknown"
|
"quickfix": "unknown"
|
||||||
}
|
}
|
||||||
|
8
rules/S3431/resources.adoc
Normal file
8
rules/S3431/resources.adoc
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
== Resources
|
||||||
|
|
||||||
|
=== Documentation
|
||||||
|
|
||||||
|
* Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.testtools.unittesting.assert.throwsexception[Assert.ThrowsException Method]
|
||||||
|
* Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.testtools.unittesting.expectedexceptionattribute[ExpectedExceptionAttribute Class]
|
||||||
|
* NUnit - https://docs.nunit.org/articles/nunit/writing-tests/assertions/classic-assertions/Assert.Throws.html[Assert.Throws]
|
||||||
|
* NUnit - https://docs.nunit.org/2.4/exception.html[ExpectedExceptionAttribute]
|
31
rules/S3431/vbnet/flow-example.adoc
Normal file
31
rules/S3431/vbnet/flow-example.adoc
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
[source,vbnet]
|
||||||
|
----
|
||||||
|
<TestMethod>
|
||||||
|
<ExpectedException(GetType(InvalidOperationException))>
|
||||||
|
Public Sub UsingTest()
|
||||||
|
Console.ForegroundColor = ConsoleColor.Black
|
||||||
|
Try
|
||||||
|
Using alert As New ConsoleAlert()
|
||||||
|
Assert.AreEqual(ConsoleColor.Red, Console.ForegroundColor)
|
||||||
|
Throw New InvalidOperationException()
|
||||||
|
End Using
|
||||||
|
Finally
|
||||||
|
Assert.AreEqual(ConsoleColor.Black, Console.ForegroundColor) ' The exception itself is not relevant for the test.
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public NotInheritable Class ConsoleAlert
|
||||||
|
Implements IDisposable
|
||||||
|
|
||||||
|
Private ReadOnly previous As ConsoleColor
|
||||||
|
|
||||||
|
Public Sub New()
|
||||||
|
previous = Console.ForegroundColor
|
||||||
|
Console.ForegroundColor = ConsoleColor.Red
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public Sub Dispose() Implements IDisposable.Dispose
|
||||||
|
Console.ForegroundColor = previous
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
|
----
|
28
rules/S3431/vbnet/how-mstest.adoc
Normal file
28
rules/S3431/vbnet/how-mstest.adoc
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
== How to fix it in MSTest
|
||||||
|
|
||||||
|
Remove the `ExpectedException` attribute in favor of using the https://learn.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.testtools.unittesting.assert.throwsexception[Assert.ThrowsException] assertion.
|
||||||
|
|
||||||
|
=== Code examples
|
||||||
|
|
||||||
|
==== Noncompliant code example
|
||||||
|
|
||||||
|
[source,vbnet,diff-id=1,diff-type=noncompliant]
|
||||||
|
----
|
||||||
|
<TestMethod>
|
||||||
|
<ExpectedException(GetType(ArgumentNullException))> ' Noncompliant
|
||||||
|
Public Sub Method_NullParam()
|
||||||
|
Dim sut As New MyService()
|
||||||
|
sut.Method(Nothing)
|
||||||
|
End Sub
|
||||||
|
----
|
||||||
|
|
||||||
|
==== Compliant solution
|
||||||
|
|
||||||
|
[source,vbnet,diff-id=1,diff-type=compliant]
|
||||||
|
----
|
||||||
|
<TestMethod>
|
||||||
|
Public Sub Method_NullParam()
|
||||||
|
Dim sut As New MyService()
|
||||||
|
Assert.ThrowsException(Of ArgumentNullException)(Sub() sut.Method(Nothing))
|
||||||
|
End Sub
|
||||||
|
----
|
28
rules/S3431/vbnet/how-nunit.adoc
Normal file
28
rules/S3431/vbnet/how-nunit.adoc
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
== How to fix it in NUnit
|
||||||
|
|
||||||
|
Remove the `ExpectedException` attribute in favor of using the https://docs.nunit.org/articles/nunit/writing-tests/assertions/classic-assertions/Assert.Throws.html[Assert.Throws] assertion.
|
||||||
|
|
||||||
|
=== Code examples
|
||||||
|
|
||||||
|
==== Noncompliant code example
|
||||||
|
|
||||||
|
[source,vbnet,diff-id=2,diff-type=noncompliant]
|
||||||
|
----
|
||||||
|
<Test>
|
||||||
|
<ExpectedException(GetType(ArgumentNullException))> ' Noncompliant
|
||||||
|
Public Sub Method_NullParam()
|
||||||
|
Dim sut As New MyService()
|
||||||
|
sut.Method(Nothing)
|
||||||
|
End Sub
|
||||||
|
----
|
||||||
|
|
||||||
|
==== Compliant solution
|
||||||
|
|
||||||
|
[source,vbnet,diff-id=2,diff-type=compliant]
|
||||||
|
----
|
||||||
|
<Test>
|
||||||
|
Public Sub Method_NullParam()
|
||||||
|
Dim sut As New MyService()
|
||||||
|
Assert.Throws(Of ArgumentNullException)(Sub() sut.Method(Nothing))
|
||||||
|
End Sub
|
||||||
|
----
|
@ -1,46 +1,18 @@
|
|||||||
|
include::../../../shared_content/dotnet/vbnet_dictionary.adoc[]
|
||||||
|
:language: vbnet
|
||||||
|
|
||||||
== Why is this an issue?
|
== Why is this an issue?
|
||||||
|
|
||||||
include::../description.adoc[]
|
include::../description.adoc[]
|
||||||
|
|
||||||
=== Noncompliant code example
|
|
||||||
|
|
||||||
[source,vbnet]
|
|
||||||
----
|
|
||||||
<TestMethod>
|
|
||||||
<ExpectedException(GetType(ArgumentNullException))> ' Noncompliant
|
|
||||||
Public Sub TestNullArg()
|
|
||||||
'...
|
|
||||||
End Sub
|
|
||||||
----
|
|
||||||
|
|
||||||
=== Compliant solution
|
|
||||||
|
|
||||||
[source,vbnet]
|
|
||||||
----
|
|
||||||
<TestMethod>
|
|
||||||
Public Sub TestNullArg()
|
|
||||||
Dim CallFailed As Boolean = False
|
|
||||||
Try
|
|
||||||
' ...
|
|
||||||
Catch ex As Exception
|
|
||||||
CallFailed = true
|
|
||||||
End Try
|
|
||||||
Assert.IsTrue(CallFailed, "Expected call to MyMethod to fail with ArgumentNullException")
|
|
||||||
End Sub
|
|
||||||
----
|
|
||||||
|
|
||||||
or
|
|
||||||
|
|
||||||
[source,vbnet]
|
|
||||||
----
|
|
||||||
<TestMethod>
|
|
||||||
Public Sub TestNullArg()
|
|
||||||
Assert.ThrowsException(Of ArgumentNullException)(Sub() ... )
|
|
||||||
End Sub
|
|
||||||
----
|
|
||||||
|
|
||||||
include::../exceptions.adoc[]
|
include::../exceptions.adoc[]
|
||||||
|
|
||||||
|
include::./how-mstest.adoc[]
|
||||||
|
|
||||||
|
include::./how-nunit.adoc[]
|
||||||
|
|
||||||
|
include::../resources.adoc[]
|
||||||
|
|
||||||
ifdef::env-github,rspecator-view[]
|
ifdef::env-github,rspecator-view[]
|
||||||
'''
|
'''
|
||||||
== Comments And Links
|
== Comments And Links
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
:keyword_null: null
|
:keyword_null: null
|
||||||
:keyword_async: async
|
:keyword_async: async
|
||||||
|
:keyword_catch: catch
|
||||||
|
:keyword_finally: finally
|
||||||
:concept_method: method
|
:concept_method: method
|
||||||
:typeparameter_TResult: <TResult>
|
:typeparameter_TResult: <TResult>
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
:keyword_null: Nothing
|
:keyword_null: Nothing
|
||||||
:keyword_async: Async
|
:keyword_async: Async
|
||||||
|
:keyword_catch: Catch
|
||||||
|
:keyword_finally: Finally
|
||||||
:concept_method: procedure
|
:concept_method: procedure
|
||||||
:typeparameter_TResult: (Of TResult)
|
:typeparameter_TResult: (Of TResult)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user