TUnit.Mocks: Is<T>(predicate) passes T? for non-nullable T, forcing null guards (CS8602)

Open Beginner friendly
#7,304 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

@thomhurst is already working on this.

Since Nov 2, 2026.

  • #7405 by @thomhurst — open

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
65/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
csharp
Domain
testing

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

bug P2
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

Open in Codespaces

Starts the project's dev container in your browser, under your own GitHub account.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from thomhurst/TUnit

All issues in thomhurst/TUnit

Similar issues

More C# issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.