Mocking generic methods in Moq without specifying T
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Mocking generic methods in C# with Moq becomes difficult when you do not know the type parameter T at compile time. Moq's Setup requires a concrete type for generic parameters, so mock.Setup(x => x.Get<T>(...)) does not compile when T is unknown. The workaround depends on your scenario: if you know the finite set of types, set up each one explicitly. If the type is truly open, use reflection to invoke Setup dynamically, or redesign the interface to avoid open generics. This article covers all approaches with working examples.
The Problem
Moq uses expression trees internally, and expression trees require concrete types at compile time. You cannot pass an open generic parameter to Setup.
Fix 1: Set Up Each Known Type Explicitly
This is the simplest and most readable approach. In most unit tests, you know exactly which types the code under test will request.
Fix 2: Helper Method with Generic Constraint
A generic helper method reduces repetition when you need to set up many types with the same pattern.
Fix 3: Reflection for Truly Open Generics
Reflection-based approaches are fragile and hard to maintain. In practice, the explicit per-type setup is almost always better.
Fix 4: Redesign the Interface
If you control the interface, making it generic at the interface level (not method level) sidesteps the problem entirely. Each mock targets a specific T.
Fix 5: Using Moq Callbacks as a Workaround
Callbacks give you runtime control over the return value while keeping the setup type-safe and readable.
Verifying Generic Method Calls
Common Pitfalls
- Trying to use an open generic in Setup:
mock.Setup(x => x.Get<T>(...))whereTis a type parameter does not compile. You must supply a concrete type likeGet<User>. - Forgetting to set up all used types: If the code under test calls
Get<Order>but you only set upGet<User>, Moq returnsdefault(Order)(null for reference types), which may causeNullReferenceExceptiondownstream. - Over-engineering with reflection: Reflection-based generic setups are brittle, hard to debug, and rarely necessary. Prefer explicit setups for each concrete type.
- Not verifying the type parameter:
mock.Verify(x => x.Save(It.IsAny<User>()))only verifies calls withT = User. A call toSave<Order>does not match, which may hide bugs. - Ignoring interface redesign: If you find yourself needing open-generic mocks frequently, the interface design may be the real problem. Generic interfaces (
IRepository<T>) are easier to mock than generic methods.
Summary
- Moq requires concrete types for generic method setups — open
Tdoes not compile - The simplest fix is setting up each known type explicitly (
Get<User>,Get<Order>, etc.) - Use a generic helper method to reduce boilerplate when setting up many types
- Reflection-based approaches work but are fragile and rarely worth the complexity
- Redesigning the interface from generic methods to generic interfaces makes mocking straightforward
- Always verify generic method calls with the correct type parameter to catch bugs

