From 28b04125a5003124cd04d92ec70674f468725f08 Mon Sep 17 00:00:00 2001 From: Richard Murillo Date: Sun, 8 Mar 2026 18:54:13 -0700 Subject: [PATCH 1/4] fix: update test to expect diagnostic for generic callback type mismatch The analyzer now correctly detects type mismatches in generic Callback() syntax after symbol-based detection was introduced in PR #1030. The previous 'known limitation' test expected no diagnostic, but the analyzer now correctly produces Moq1100. Co-Authored-By: Claude Opus 4.6 --- ...ureShouldMatchMockedMethodAnalyzerTests.cs | 26 ++++++------------- 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/tests/Moq.Analyzers.Test/CallbackSignatureShouldMatchMockedMethodAnalyzerTests.cs b/tests/Moq.Analyzers.Test/CallbackSignatureShouldMatchMockedMethodAnalyzerTests.cs index 2dc220835..d9dc53bc5 100644 --- a/tests/Moq.Analyzers.Test/CallbackSignatureShouldMatchMockedMethodAnalyzerTests.cs +++ b/tests/Moq.Analyzers.Test/CallbackSignatureShouldMatchMockedMethodAnalyzerTests.cs @@ -218,26 +218,17 @@ public void TestMethod() } /// - /// Test to document the known limitation with generic callback validation. - /// This test documents that .Callback<T>() with wrong type parameters is NOT currently validated. - /// This is an accepted limitation as the explicit generic syntax is rarely used in practice. + /// Verifies that .Callback<T>() with a wrong type parameter produces a diagnostic. + /// Symbol-based detection (PR #1030) resolved the previous limitation where the generic + /// Callback syntax was not validated. The analyzer now correctly detects the type mismatch + /// between .Callback<int>() and the mocked method parameter type (string). /// - /// - /// - /// Analysis shows zero real-world usage of the explicit generic .Callback<T>() syntax in open-source projects. - /// The recommended approach is to use lambda parameter inference which provides full type validation: - /// .Callback(param => { }) or .Callback((string param) => { }). - /// - /// - /// See docs/rules/Moq1100.md "Known Limitations" section for best practices. - /// - /// /// The Moq version reference assembly group. /// A task representing the asynchronous unit test. [Theory] [InlineData("Net80WithOldMoq")] [InlineData("Net80WithNewMoq")] - public async Task GenericCallbackValidation_CurrentLimitation_IsDocumented(string referenceAssemblyGroup) + public async Task GenericCallbackWithWrongType_ProducesDiagnostic(string referenceAssemblyGroup) { const string source = """ using Moq; @@ -252,15 +243,14 @@ public class TestClass public void TestGenericCallback() { var mock = new Mock(); - // Note: This does NOT trigger a diagnostic (known limitation) - // Best practice: Use .Callback(param => { }) instead of .Callback(param => { }) + // .Callback() mismatches the mocked method parameter type (string). + // The analyzer detects this via symbol-based resolution of the generic type argument. mock.Setup(x => x.DoWork("test")) - .Callback(wrongTypeParam => { }); // Generic syntax not validated + .Callback({|Moq1100:wrongTypeParam|} => { }); } } """; - // This test documents the known limitation - no diagnostic is expected await AnalyzerVerifier.VerifyAnalyzerAsync(source, referenceAssemblyGroup); } } From 7f1a8e2c33377e90a2a6d0df5652dbb5a0b004ed Mon Sep 17 00:00:00 2001 From: Richard Murillo Date: Sun, 8 Mar 2026 18:57:08 -0700 Subject: [PATCH 2/4] docs: update Moq1100 to reflect generic callback validation support Co-Authored-By: Claude Opus 4.6 --- docs/rules/Moq1100.md | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/docs/rules/Moq1100.md b/docs/rules/Moq1100.md index 51b52041e..efe9c9324 100644 --- a/docs/rules/Moq1100.md +++ b/docs/rules/Moq1100.md @@ -108,32 +108,26 @@ mock.Setup(x => x.TryProcess(out It.Ref.IsAny)) .Returns(true); ``` -## Known Limitations +## Coverage Notes ### Generic Callback Syntax -This analyzer does **not** currently validate type parameter mismatches when using the explicit generic `.Callback()` syntax. For example: +This analyzer validates type parameter mismatches in both lambda parameter inference and explicit generic `.Callback()` syntax. For example: ```csharp -// This will NOT trigger a diagnostic (current limitation) -mock.Setup(x => x.DoWork("test")) // DoWork takes a string parameter - .Callback(wrongTypeParam => { }); // Using int instead of string - no warning! +// This WILL trigger Moq1100 - type mismatch detected +mock.Setup(x => x.DoWork("test")) + .Callback(wrongTypeParam => { }); ``` -**Best Practice:** Use lambda parameter inference instead of explicit generic syntax to get full validation: +**Recommended:** Use lambda parameter inference for clarity and readability: ```csharp -// ✅ Recommended: Let the compiler infer parameter types -mock.Setup(x => x.DoWork("test")) - .Callback(param => { }); // Type is inferred correctly as string - -// ✅ Also recommended: Explicitly type the lambda parameter +// Preferred style - clear and validated mock.Setup(x => x.DoWork("test")) - .Callback((string param) => { }); // Type validation works correctly + .Callback((string input) => { }); ``` -**Rationale:** The explicit generic `.Callback()` syntax is rarely used in practice. Analysis of open-source Moq usage found zero instances of this pattern. The recommended lambda parameter inference approach provides full type safety and validation coverage. - ## Suppress a warning If you just want to suppress a single violation, add preprocessor directives to From 5d5613572d5c9ed01c82127adde5f42e942595fc Mon Sep 17 00:00:00 2001 From: Richard Murillo Date: Sun, 8 Mar 2026 19:01:40 -0700 Subject: [PATCH 3/4] docs: clarify generic callback detection mechanism in test comment Co-Authored-By: Claude Opus 4.6 --- ...CallbackSignatureShouldMatchMockedMethodAnalyzerTests.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Moq.Analyzers.Test/CallbackSignatureShouldMatchMockedMethodAnalyzerTests.cs b/tests/Moq.Analyzers.Test/CallbackSignatureShouldMatchMockedMethodAnalyzerTests.cs index d9dc53bc5..656c26fbf 100644 --- a/tests/Moq.Analyzers.Test/CallbackSignatureShouldMatchMockedMethodAnalyzerTests.cs +++ b/tests/Moq.Analyzers.Test/CallbackSignatureShouldMatchMockedMethodAnalyzerTests.cs @@ -219,9 +219,9 @@ public void TestMethod() /// /// Verifies that .Callback<T>() with a wrong type parameter produces a diagnostic. - /// Symbol-based detection (PR #1030) resolved the previous limitation where the generic - /// Callback syntax was not validated. The analyzer now correctly detects the type mismatch - /// between .Callback<int>() and the mocked method parameter type (string). + /// The analyzer uses symbol-based resolution of the generic type argument to validate the + /// callback parameter type. It correctly detects the type mismatch between .Callback<int>() + /// and the mocked method parameter type (string). /// /// The Moq version reference assembly group. /// A task representing the asynchronous unit test. From 2de610c15784b2d0110d0dd7d60fd02c93af508a Mon Sep 17 00:00:00 2001 From: Richard Murillo Date: Sun, 8 Mar 2026 19:06:57 -0700 Subject: [PATCH 4/4] style: use tags and curly brace notation in XML doc comments Co-Authored-By: Claude Opus 4.6 --- ...CallbackSignatureShouldMatchMockedMethodAnalyzerTests.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Moq.Analyzers.Test/CallbackSignatureShouldMatchMockedMethodAnalyzerTests.cs b/tests/Moq.Analyzers.Test/CallbackSignatureShouldMatchMockedMethodAnalyzerTests.cs index 656c26fbf..4005518e7 100644 --- a/tests/Moq.Analyzers.Test/CallbackSignatureShouldMatchMockedMethodAnalyzerTests.cs +++ b/tests/Moq.Analyzers.Test/CallbackSignatureShouldMatchMockedMethodAnalyzerTests.cs @@ -218,10 +218,10 @@ public void TestMethod() } /// - /// Verifies that .Callback<T>() with a wrong type parameter produces a diagnostic. + /// Verifies that .Callback{T}() with a wrong type parameter produces a diagnostic. /// The analyzer uses symbol-based resolution of the generic type argument to validate the - /// callback parameter type. It correctly detects the type mismatch between .Callback<int>() - /// and the mocked method parameter type (string). + /// callback parameter type. It correctly detects the type mismatch between .Callback{int}() + /// and the mocked method parameter type (string). /// /// The Moq version reference assembly group. /// A task representing the asynchronous unit test.