Repository navigation
feat(mocks): argument-aware Returns for Task/ValueTask members - #7404
Conversation
…sk members (#7301) Members returning non-generic Task/ValueTask only had parameterless task factories, so the returned task could not depend on the call's arguments. Generate typed Returns/ReturnsAsync(Func<params..., Task|ValueTask>) overloads on their wrappers, backed by a new args-aware ReturnsRaw on VoidMethodSetupBuilder.
|
@codex review |
|
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Raw return support and generated overloads src/TUnit.Mocks/Setup/VoidMethodSetupBuilder.cs, src/TUnit.Mocks.SourceGenerator/Builders/MockMembersBuilder.cs |
Void method setups register raw factories that receive call arguments. Generated async wrappers emit typed Returns and ReturnsAsync factories for non-generic Task and ValueTask methods. |
Regression coverage and migration guidance tests/TUnit.Mocks.SourceGenerator.Tests/Snapshots/*, tests/TUnit.Mocks.Tests/Issue7301Tests.cs, docs/docs/migration/mocking/moq.md |
Snapshots and tests cover argument passing, task handoff, pending completion, callback invocation, and factory exceptions. The migration guide documents these factories. |
Estimated code review effort: 3 (Moderate) | ~20 minutes
Change: Feature · Severity of issue fixed: Medium
Sequence Diagram(s)
sequenceDiagram
participant Caller
participant GeneratedMockCall
participant VoidMethodSetupBuilder
participant ComputedRawReturnWithArgsBehavior
Caller->>GeneratedMockCall: configure Returns or ReturnsAsync factory
GeneratedMockCall->>VoidMethodSetupBuilder: register factory through ReturnsRaw
VoidMethodSetupBuilder->>ComputedRawReturnWithArgsBehavior: store factory
Caller->>GeneratedMockCall: call mocked method
GeneratedMockCall->>ComputedRawReturnWithArgsBehavior: pass call arguments
ComputedRawReturnWithArgsBehavior-->>Caller: return factory-produced Task or ValueTask
Suggested reviewers: quattordici
Merge Risk: 
Minimal · up to 895c3
-
The new factories pass through their tasks. No merge-blocking issue was established.
Pre-merge checks: 
4 · 
1
-
Failed checks: 1 warning Passed checks: 4 passed-
Full details: Linked Issues check
-
Explanation
Issue
#7301is open and directly linked. The generator now emits typedReturnsAsync(Func<... , Task|ValueTask>)and matchingReturns(Func<... , Task|ValueTask>)overloads for non-genericTaskandValueTaskmembers. The overloads pass actual call arguments to the factory and return the produced task unchanged throughReturnsRaw. The newIssue7301Testscover argument flow, callback invocation, pending async tasks, task identity, and factory exceptions. The snapshots and migration documentation also cover the new API.
Full details: Out of Scope Changes check
-
Explanation
The changes stay within Issue
#7301. The source-generator changes implement the required overloads.VoidMethodSetupBuilder.ReturnsRawsupports the generated argument-aware setup path. Snapshot updates, regression tests, and the Moq migration note document and validate the same feature. No unrelated implementation is shown in the pull-request diff.
-
Full details: Docstring Coverage
-
Explanation
Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 2 functions across 3 files. (3 skipped: 3 unsupported.)
Resolution
Write docstrings for the functions missing them to satisfy the coverage threshold.
-
Finishing Touches
-
Generate docstrings
-
- Commit to this branch
- Create a new PR
Generate unit tests (beta)
-
- Commit to this branch
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
A rabbit taps a task into the night
Call arguments guide it on its way
A ValueTask waits until its gate
Then callback paws spring into play
The factory hands its task back whole
And tests record each hop and stay
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Review: argument-aware Returns for Task/ValueTask membersLooks good. I found nothing blocking.
Minor suggestions, not blocking:
I couldn't run the tests here. The PR reports a full pass on net8.0, net9.0 and net10.0. net472 is left to CI. Approve. |
|
Codex Review: Didn't find any major issues. Delightful! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
[Medium impact] This PR appears safe to merge. SummaryAdds argument-aware factories for members returning
|
ReviewThis looks good. I found nothing blocking.
Optional:
Approve from my side. |
Summary
Members returning non-generic
Task/ValueTaskonly had parameterless task factories (Returns(Func<Task>),ReturnsAsync(Func<Task>)), so a mock could not return a task built from the call's arguments. Moq supports this, so it comes up in Moq migrations.ReturnsAsync(Func<T1..Tn, Task|ValueTask>)and aReturns(...)alias with the same shape on wrappers for bareTask/ValueTaskmembers. This matches whatTask<T>members already get. The factory's task is returned unchanged, so anasynclambda stays pending until it completes.VoidMethodSetupBuildergets an[EditorBrowsable(Never)]ReturnsRaw(Func<object?[], object?>), which mirrors the existing one onMethodSetupBuilder<TReturn>.Returns(Func<...>)sibling, so the alias doesn't need the generic/ORP shape thatTask<T>members use.Validation
tests/TUnit.Mocks.Tests(newIssue7301Testsplus the full suite): 4339 passed on net8.0, net9.0 and net10.0.tests/TUnit.Mocks.SourceGenerator.Tests: 582 passed. The two updated snapshots (Interface_With_Async_Methods,Delegates_Returning_Task_And_ValueTask) only add the new overloads.tests/TUnit.PublicAPI: 74 passed. TUnit.Mocks isn't covered by those snapshots.Closes #7301
Summary by CodeRabbit
TaskorValueTaskwith factories that receive the call’s arguments. The factory’s task is returned unchanged, allowing asynchronous work to remain pending until it completes.ReturnsandReturnsAsyncfactories work for asynchronous methods without a result.