TUnit.Mocks: Is<T>(predicate) passes T? for non-nullable T, forcing null guards (CS8602)
Maintainers usually reply within 1 day
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 65/100
Research direction
Start by locating the Is<T>(...) declaration in TUnit.Mocks and reading its existing tests and nullable annotations. Reproduce the reported CS8602 warning with nullable reference types enabled, then check how the API distinguishes non-nullable and nullable T. Done means the non-nullable predicate example compiles without a null guard while Is<User?> can still match null.
Written by the indexing model from the issue text.
Description
Description
With nullable reference types enabled, the predicate passed to Is<T>(...) receives T? even when T is a non-nullable reference type. Every predicate that dereferences its argument then needs a null guard to avoid CS8602, which makes the common case noisy:
mock.Save(Is<User>(u => u.Name == "Alice")); // CS8602: Dereference of a possibly null reference.
mock.Save(Is<User>(u => u is not null && u.Name == "Alice")); // compiles
During a Moq migration of a large test suite this needed a null guard in a few dozen predicates. Moq's It.Is<User>(u => u.Name == "Alice") passes User, not User?.
Repro (TUnit.Mocks 1.76.45, net10.0, <Nullable>enable</Nullable>, warnings as errors)
public record User(string Name);
public interface IRepo { void Save(User user); }
var mock = Mock.Of<IRepo>();
mock.Save(Is<User>(u => u.Name == "Alice")).WasCalled(); // CS8602
Expected
When T is a non-nullable reference type, the predicate parameter is T (and a null argument simply does not match, as with Any<T>() vs IsNull<T>()). Is<User?>(u => ...) would still give the nullable form when a test wants to match null.
- Dominant language
- C#
- Stars
- 4k
- Forks
- 139
- Avg merge
- 8h 50m
- Merged PRs (30d)
- 255
Getting set up
Starts the project's dev container in your browser, under your own GitHub account.
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from thomhurst/TUnit
-
enhancement P3 performance
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
thomhurst/TUnit#7380 · 2 comments ·
Maintainers usually reply within 1 day
-
bug github_actions P2
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
thomhurst/TUnit#7229 · 1 comment ·
Maintainers usually reply within 1 day
-
enhancement P3
Difficulty 2/5 1-3 hours Newbie friendliness 73/100
thomhurst/TUnit#7194 · 1 comment ·
Maintainers usually reply within 1 day
-
enhancement P3
Difficulty 3/5 1-2 days Newbie friendliness 55/100
Maintainers usually reply within 1 day
-
bug P2
Difficulty 4/5 3-5 days Newbie friendliness 20/100
Maintainers usually reply within 1 day
Similar issues
-
effort:S P3 refactor
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
nightscout/nocturne#3243 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
dasher-project/Dasher-Windows#84 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
libnativeapi/nativeapi#21 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Maintainers usually reply within 3 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100