KnockOff supports nine distinct patterns for creating test stubs, organized into two categories:
Standalone Patterns (file-based, reusable across tests):
- Standalone - Dedicated stub class implementing interface
- Generic Standalone - Generic stub class with type parameters
- Standalone Class - Dedicated stub class for concrete/abstract classes
- Generic Standalone Class - Generic stub class for generic base classes
Inline Patterns (nested within test class):
- Inline Interface - Nested stub for closed generic interface
- Inline Class - Nested stub for class with virtual members
- Inline Delegate - Nested stub for delegate types
- Open Generic Interface - Nested generic stub from open generic interface
- Open Generic Class - Nested generic stub from open generic class
All KnockOff classes must be
partial. Standalone stub classes must bepartialso the generator can emit a base class. Inline pattern test classes must bepartialso the generator can emit nestedStubstypes. If you forgetpartial, the generator silently skips your class and nothing is generated.
Internal types are fully supported. When the target interface, class, or delegate is
internal, the generated stub class usesinternalaccessibility. For standalone patterns, declare the stub class asinternal partial classand the generated Base class will match. For inline patterns, the generator automatically matches the target type's accessibility. See the API Consistency Matrix for details.
Standalone Patterns (file-based, reusable)
|-- 1. Standalone - [KnockOff] class Stub : IFoo
|-- 2. Generic Standalone - [KnockOff] class Stub<T> : IFoo<T>
|-- 3. Standalone Class - [KnockOffBase<SomeClass>] class Stub
|-- 4. Generic Standalone Class - [KnockOffBase(typeof(ClassBase<>))] class Stub<T>
Inline Patterns (nested within test class)
|-- 5. Inline Interface - [KnockOff<IFoo>]
|-- 6. Inline Class - [KnockOff<SomeClass>]
|-- 7. Inline Delegate - [KnockOff<SomeDelegate>]
|-- 8. Open Generic Interface - [KnockOff(typeof(IFoo<>))]
|-- 9. Open Generic Class - [KnockOff(typeof(SomeClass<>))]
| If you need... | Use this pattern |
|---|---|
| Reusable interface stub across multiple test files | Standalone |
| Custom methods on your interface stub | Standalone |
| Reusable generic interface stub with type parameters | Generic Standalone |
| Reusable class stub across multiple test files | Standalone Class |
| Custom methods on your class stub | Standalone Class |
| Reusable generic class stub with type parameters | Generic Standalone Class |
| Quick, test-local stub | Inline Interface |
| No extra stub files | Inline Interface |
| Stub a class (not interface) for one test class | Inline Class |
| Stub a delegate type | Inline Delegate |
| Test-local stub for generic interface | Open Generic Interface |
| Test-local stub for generic class | Open Generic Class |
The Standalone pattern creates a dedicated stub class in its own file. This stub can be reused across test files and supports adding custom methods.
- You need the same stub in multiple test files
- You want to add helper methods or custom behavior to the stub
- You prefer explicit, discoverable stub classes in IntelliSense
- You need the cleanest instantiation syntax (
new MyStub())
public interface IUserRepoStandalone
{
User? GetById(int id);
void Save(User user);
}
[KnockOff]
public partial class UserRepoStandaloneStub : IUserRepoStandalone { } // Stub classes MUST be partial// Stand-Alone: instantiate like any class, configure via Verify()
var stub = new UserRepoStandaloneStub();
stub.GetById.Call((id) => new User { Id = id, Name = $"User{id}" }).Verifiable();
stub.Save.Call((user) => { }).Verifiable();- Reusable: Reference the stub from any test file
- Stub overrides: Add custom methods and override properties directly on the stub class
- Discoverable: Appears in IntelliSense when browsing your test project
- Explicit: Clear separation between test code and stub implementation
- Clean syntax: Simple
new MyStub()instantiation
- Extra file: Requires a dedicated .cs file for each stub
- Partial class: Must remember to mark the class as
partial - Manual interface: Must manually implement the interface signature
The Standalone pattern generates a base class (e.g., UserRepoStandaloneStubBase) that your stub inherits from. This base class exposes protected virtual methods and properties for each interface member, allowing you to add custom stub behavior through inheritance.
Override these members using the underscore suffix convention (_) to provide default implementations:
[KnockOff]
public partial class UserRepoWithStubOverridesStub : IUserRepoStandalone // Stub classes MUST be partial
{
// Override base class method with underscore suffix
protected override User? GetById_(int id)
{
return new User { Id = id, Name = "Default User" };
}
}The interceptor name remains clean (GetById), while your implementation uses the suffix (GetById_). This keeps stub overrides separate from the generated code. See Stub Overrides for methods and Properties Guide for stub override properties.
The Generic Standalone pattern creates a reusable generic stub class that can be instantiated with different type arguments across your test suite.
- You need a reusable stub for a generic interface (e.g.,
IRepository<T>) - You want to use the same stub definition with different type arguments
- You need the same stub in multiple test files with various types
- You prefer clean instantiation syntax with type parameters
public interface IRepositoryGeneric<T> where T : class
{
T? GetById(int id);
void Save(T entity);
IEnumerable<T> GetAll();
}
[KnockOff]
public partial class RepositoryGenericStub<T> : IRepositoryGeneric<T> where T : class { } // Stub classes MUST be partial// Generic Standalone: reusable across multiple type arguments
var userRepo = new RepositoryGenericStub<User>();
userRepo.GetById.Call((id) => new User { Id = id, Name = "Test" }).Verifiable();
userRepo.Save.Call((entity) => { }).Verifiable();
var productRepo = new RepositoryGenericStub<Product>();
productRepo.GetById.Call((id) => new Product { Id = id, Name = "Widget" }).Verifiable();- Single definition: Define once, use with any type argument
- Reusable: Share across multiple test files
- Type-safe: Compiler enforces type constraints
- Clean syntax:
new RepositoryStub<User>()- clear and readable - Stub overrides: Supports custom helper methods and property overrides like Standalone
- Extra file: Requires a dedicated .cs file for the stub
- Partial class: Must mark as
partial - Constraints must match: Type constraints must mirror the interface
| Aspect | Generic Standalone | Open Generic |
|---|---|---|
| Syntax | [KnockOff] class Stub<T> : IFoo<T> |
[KnockOff(typeof(IFoo<>))] |
| Instantiation | new Stub<User>() |
new Stubs.IFoo<User>() |
| Reusability | Across test files | Within one test class |
| Stub overrides | Yes | No |
| Best for | Shared generic stubs | One-time use |
The Standalone Class pattern creates a dedicated stub class for concrete or abstract classes in its own file. This stub can be reused across test files and supports adding custom methods.
- You need the same class stub in multiple test files
- You want to add helper methods or custom behavior to the stub
- The class has virtual or abstract members you want to intercept
- You prefer explicit, discoverable stub classes in IntelliSense
- You cannot or don't want to extract an interface
public abstract class ServiceBaseNonGeneric
{
public abstract string Name { get; }
public abstract void Execute(string command);
}
[KnockOffBase<ServiceBaseNonGeneric>]
public partial class ServiceBaseStub { } // Stub classes MUST be partial// Standalone Class: configure stub, use .Object for the class instance
var stub = new ServiceBaseStub();
stub.Name.Get(() => "test").Verifiable();
stub.Execute.Call((cmd) => { }).Verifiable();
ServiceBaseNonGeneric service = stub.Object;- Reusable: Reference the stub from any test file
- Stub overrides: Add custom methods and override properties directly on the stub class
- Discoverable: Appears in IntelliSense when browsing your test project
- Explicit: Clear separation between test code and stub implementation
- No interface needed: Stub classes directly without creating interfaces
- Extra file: Requires a dedicated .cs file for each stub
- Partial class: Must remember to mark the class as
partial - Must use .Object: The stub is a wrapper; use
.Objectproperty to get the actual instance - Virtual/abstract only: Only overrides members marked
virtualorabstract
| Aspect | Standalone Class | Inline Class |
|---|---|---|
| Syntax | [KnockOffBase<Foo>] class Stub |
[KnockOff<Foo>] |
| Instantiation | new ServiceStub().Object |
new Stubs.Service().Object |
| Reusability | Across test files | Within one test class |
| Stub overrides | Yes | No |
| Best for | Shared class stubs | One-time use |
The Generic Standalone Class pattern creates a reusable generic stub class for generic base classes that can be instantiated with different type arguments across your test suite.
- You need a reusable stub for a generic class (e.g.,
RepositoryBase<T>,ServiceBase<T>) - You want to use the same stub definition with different type arguments
- You need the same stub in multiple test files with various types
- The class has virtual or abstract members you want to intercept
- You prefer clean instantiation syntax with type parameters
public abstract class RepositoryBase<T> where T : class
{
public abstract T? GetItem(int id);
public abstract void Save(T entity);
}
[KnockOffBase(typeof(RepositoryBase<>))]
public partial class RepositoryBaseStub<T> where T : class { } // Stub classes MUST be partial// Generic Standalone Class: reusable across multiple type arguments, uses .Object
var stub = new RepositoryBaseStub<User>();
stub.GetItem.Call((id) => new User { Id = id, Name = "Test" }).Verifiable();
stub.Save.Call((entity) => { }).Verifiable();
RepositoryBase<User> service = stub.Object;- Single definition: Define once, use with any type argument
- Reusable: Share across multiple test files
- Type-safe: Compiler enforces type constraints
- Clean syntax:
new RepositoryStub<User>().Object- clear and readable - Stub overrides: Supports custom helper methods and property overrides like Standalone patterns
- No interface needed: Stub generic classes directly
- Extra file: Requires a dedicated .cs file for the stub
- Partial class: Must mark as
partial - Constraints must match: Type constraints must mirror the base class
- Must use .Object: The stub is a wrapper; use
.Objectproperty to get the actual instance - Virtual/abstract only: Only overrides members marked
virtualorabstract
| Aspect | Generic Standalone Class | Open Generic Class |
|---|---|---|
| Syntax | [KnockOffBase(typeof(Foo<>))] class Stub<T> |
[KnockOff(typeof(Foo<>))] |
| Instantiation | new Stub<User>().Object |
new Stubs.Foo<User>().Object |
| Reusability | Across test files | Within one test class |
| Stub overrides | Yes | No |
| Best for | Shared generic class stubs | One-time use |
The Inline Interface pattern generates a stub class scoped to your test class. The stub is accessed through a nested Stubs namespace.
- You need a stub only within one test class
- You don't need custom methods on the stub
- You want minimal ceremony and no extra files
- The interface is non-generic or you want a closed generic stub
[KnockOff<IUserRepoInline>]
public partial class InlineInterfaceTests // Test classes MUST be partial to use inline KnockOff stubs
{
// The generator creates Stubs.IUserRepoInline
}// Inline Interface: access via Stubs namespace
var stub = new Stubs.IUserRepoInline();
stub.GetById.Call((id) => new User { Id = id, Name = "Test" }).Verifiable();
stub.Save.Call((user) => { }).Verifiable();- Scoped: Stub exists only for this test class, reducing namespace pollution
- Less ceremony: No separate file, no manual interface implementation
- Automatic: Stub class generated from interface definition
- Co-located: Stub definition and usage in same file
- No stub overrides: Cannot add custom methods to the generated stub
- Stubs namespace: Must use
Stubs.IFoosyntax to instantiate - Test-local only: Cannot reuse across multiple test classes
The Inline Class pattern generates a stub for abstract or virtual class members. This allows stubbing classes without extracting interfaces.
- You need to stub a class (not an interface)
- The class has
virtualorabstractmembers you want to intercept - You cannot or don't want to extract an interface
- You're testing code that depends on a concrete class
// Target class with virtual members
public class UserServiceClass
{
public virtual User? GetUser(int id) => null;
public virtual void SaveUser(User user) { }
public virtual bool IsConnected { get; set; }
}
[KnockOff<UserServiceClass>]
public partial class InlineClassTests // Test classes MUST be partial to use inline KnockOff stubs
{
// The generator creates Stubs.UserServiceClass
}// Inline Class: configure stub, use .Object for the class instance
var stub = new Stubs.UserServiceClass();
stub.GetUser.Call((id) => new User { Id = id, Name = "FromStub" }).Verifiable();
UserServiceClass service = stub.Object;- Stub classes: Works with classes, not just interfaces
- No interface extraction: Avoids creating interfaces just for testing
- Virtual members: Intercepts any
virtualorabstractmembers - Inheritance: Properly inherits from the target class
- Must use .Object: The stub is a wrapper; use
.Objectproperty to get the actual instance - Virtual/abstract only: Only overrides members marked
virtualorabstract - No stub overrides: Cannot add custom methods like Standalone pattern
- Class limitations: Subject to any sealed/non-virtual restrictions
The Inline Delegate pattern is a specialized use of the Inline Interface pattern for delegate types. It generates a stub for delegates, allowing you to test code that accepts delegates as parameters, such as validation rules, factories, or callbacks.
- You need to stub a delegate type
- You want to track delegate invocations
- You need to configure delegate behavior in tests
- You are testing validation rules, factories, or event handlers
// Define delegate types
public delegate bool ValidationRule(string value);
public delegate T Factory<T>();
[KnockOff<ValidationRule>]
[KnockOff<Factory<User>>]
public partial class InlineDelegateTests // Test classes MUST be partial to use inline KnockOff stubs
{
// The generator creates Stubs.ValidationRule and Stubs.Factory<User>
}// Inline Delegate: configure via Interceptor, implicit conversion to delegate
var ruleStub = new Stubs.ValidationRule();
ruleStub.Interceptor.Call((value) => value != "invalid");
ValidationRule rule = ruleStub;- Implicit conversion: Stub converts to delegate type automatically
- Invocation tracking: Use
Verify(),LastArg,LastArgs - Behavior configuration: Use
Return,Call, sequences, and When chains - Async auto-wrapping:
Return(42)auto-wraps forTask<int>delegates - Verification: Use
Verify(),Calledconstraints, andVerifiable()chaining - Strict mode:
stub.Strict = truethrows on unconfigured invocations
- Interceptor property: Access tracking via
stub.Interceptor(not named member properties) - Test-local only: Cannot reuse across multiple test classes
- Named delegates only: Cannot stub
Func<T>orAction<T>directly — define a named delegate
The Open Generic Interface pattern generates a generic stub class within your test class that can be instantiated with any type argument. Use this when you need a test-local generic interface stub without creating a separate file.
- You need a generic interface stub only within one test class
- You don't need custom methods on the stub
- You want to test with multiple type arguments in one test class
- You prefer inline definition over a separate file
[KnockOff(typeof(IServiceOpenGeneric<>))]
public partial class OpenGenericTests // Test classes MUST be partial to use inline KnockOff stubs
{
// The generator creates Stubs.IServiceOpenGeneric<T>
}// Open Generic: instantiate with any type argument
var userStub = new Stubs.IServiceOpenGeneric<User>();
userStub.GetItem.Call((id) => new User { Id = id, Name = "FromStub" }).Verifiable();
var productStub = new Stubs.IServiceOpenGeneric<Product>();
productStub.GetItem.Call((id) => new Product { Id = id, Name = "FromStub" }).Verifiable();- Flexible: Use any type argument without defining separate stubs
- No extra files: Stub defined inline with tests
- Type constraints: Preserves constraints from the original generic type
- Multiple types: Use different type arguments in the same test class
- Direct assignment: Stub IS the interface implementation (no
.Objectneeded)
- Test-local only: Cannot reuse across multiple test classes
- No stub overrides: Cannot add custom methods to the generated stub
- typeof syntax: Requires
typeof(IFoo<>)with empty angle brackets - Stubs namespace: Must use
Stubs.IFoo<T>syntax
NOTE: For reusable generic stubs across multiple test files, use the Generic Standalone pattern instead.
The Open Generic Class pattern generates a generic stub class within your test class for stubbing abstract or virtual generic classes. Like the Inline Class pattern, you access the actual instance via the .Object property.
- You need to stub a generic abstract or virtual class
- You don't need custom methods on the stub
- You want to test with multiple type arguments in one test class
- You prefer inline definition over a separate file
public abstract class ServiceBaseOpenGeneric<T>
{
public abstract T? GetItem(int id);
public abstract void Process(T item);
}
[KnockOff(typeof(ServiceBaseOpenGeneric<>))]
public partial class OpenGenericClassTests // Test classes MUST be partial to use inline KnockOff stubs
{
// The generator creates Stubs.ServiceBaseOpenGeneric<T>
}// Open Generic Class: instantiate with any type argument, use .Object
var userStub = new Stubs.ServiceBaseOpenGeneric<User>();
userStub.GetItem.Call((id) => new User { Id = id, Name = "FromStub" }).Verifiable();
// IMPORTANT: .Object gives you the actual class instance
ServiceBaseOpenGeneric<User> service = userStub.Object;
var user = service.GetItem(1);
userStub.Verify();- Flexible: Use any type argument without defining separate stubs
- No extra files: Stub defined inline with tests
- Type constraints: Preserves constraints from the original generic type
- Multiple types: Use different type arguments in the same test class
- Class support: Works with abstract classes, not just interfaces
- Must use .Object: The stub is a wrapper; use
.Objectproperty to get the actual instance - Test-local only: Cannot reuse across multiple test classes
- No stub overrides: Cannot add custom methods to the generated stub
- typeof syntax: Requires
typeof(Foo<>)with empty angle brackets - Virtual/abstract only: Only overrides members marked
virtualorabstract
| Aspect | Open Generic Interface | Open Generic Class |
|---|---|---|
| Syntax | [KnockOff(typeof(IFoo<>))] |
[KnockOff(typeof(Foo<>))] |
| Instantiation | new Stubs.IFoo<T>() |
new Stubs.Foo<T>().Object |
| Assignment | IFoo<T> foo = stub; |
Foo<T> foo = stub.Object; |
| Best for | Generic interfaces | Generic abstract/virtual classes |
NOTE: For reusable generic stubs across multiple test files, use the Generic Standalone pattern instead.
| Feature | Standalone | Generic Standalone | Standalone Class | Generic Standalone Class | Inline Interface | Inline Class | Inline Delegate | Open Generic Interface | Open Generic Class |
|---|---|---|---|---|---|---|---|---|---|
| Reusable across test files | Yes | Yes | Yes | Yes | No | No | No | No | No |
| Custom stub overrides | Yes | Yes | Yes | Yes | No | No | No | No | No |
| Extra file required | Yes | Yes | Yes | Yes | No | No | No | No | No |
| Supports interfaces | Yes | Yes | No | No | Yes | No | No | Yes | No |
| Supports classes | No | No | Yes | Yes | No | Yes | No | No | Yes |
| Supports delegates | No | No | No | No | No | No | Yes | Yes* | No |
| Supports generics | No | Yes | No | Yes | Closed only | Closed only | Closed only | Yes | Yes |
| Uses .Object property | No | No | Yes | Yes | No | Yes | No | No | Yes |
| Instantiation syntax | new MyStub() |
new MyStub<T>() |
new MyStub().Object |
new MyStub<T>().Object |
new Stubs.IFoo() |
new Stubs.Foo().Object |
new Stubs.Del() |
new Stubs.IFoo<T>() |
new Stubs.Foo<T>().Object |
| Best for | Shared interface stubs | Shared generic interface stubs | Shared class stubs | Shared generic class stubs | Local interface stubs | Local class stubs | Delegate stubs | Local generic interface stubs | Local generic class stubs |
*Note: Open Generic Delegate ([KnockOff(typeof(Factory<>))]) behaves like Open Generic Interface (no .Object), as delegates are reference types that can be directly assigned.
Follow this decision tree to select the appropriate pattern:
Is it a DELEGATE type?
|-- YES --> Inline Delegate pattern
| [KnockOff<ValidationRule>]
|
|-- NO --> Is it a GENERIC interface/class?
|
|-- YES --> Do you need the stub in MULTIPLE test files?
| |
| |-- YES --> Is it a CLASS (not interface)?
| | |
| | |-- YES --> Generic Standalone Class pattern
| | | [KnockOffBase(typeof(ClassBase<>))] class Stub<T>
| | | Use: new Stub<T>().Object
| | |
| | |-- NO --> Generic Standalone pattern
| | [KnockOff] class Stub<T> : IRepo<T>
| | Use: new Stub<T>()
| |
| |-- NO --> Is it a CLASS (not interface)?
| |
| |-- YES --> Open Generic Class pattern
| | [KnockOff(typeof(ServiceBase<>))]
| | Use: new Stubs.ServiceBase<T>().Object
| |
| |-- NO --> Do you need CUSTOM METHODS on the stub?
| |
| |-- YES --> Generic Standalone pattern
| | [KnockOff] class Stub<T> : IRepo<T>
| |
| |-- NO --> Open Generic Interface pattern
| [KnockOff(typeof(IRepo<>))]
| Use: new Stubs.IRepo<T>()
|
|-- NO --> Is it a CLASS (not interface)?
|
|-- YES --> Do you need the stub in MULTIPLE test files?
| |
| |-- YES --> Standalone Class pattern
| | [KnockOffBase<SomeClass>] class Stub
| | Use: new Stub().Object
| |
| |-- NO --> Inline Class pattern
| [KnockOff<SomeClass>]
| Use: new Stubs.SomeClass().Object
|
|-- NO --> Do you need the stub in MULTIPLE test files?
|
|-- YES --> Standalone pattern
| [KnockOff] class Stub : IFoo
|
|-- NO --> Do you need CUSTOM METHODS on the stub?
|
|-- YES --> Standalone pattern
| [KnockOff] class Stub : IFoo
|
|-- NO --> Inline Interface pattern
[KnockOff<IFoo>]
| Scenario | Recommended Pattern |
|---|---|
| Interface repository stub used in 5+ test classes | Standalone |
Interface stub with WithAdminUser() helper method |
Standalone |
| Generic interface repository shared across tests | Generic Standalone |
| Class stub used in 5+ test classes | Standalone Class |
| Class stub with custom tracking methods | Standalone Class |
| Generic class repository shared across tests | Generic Standalone Class |
| Quick interface stub for single test class | Inline Interface |
Stub a DbContext with virtual DbSet properties for one test |
Inline Class |
| Stub an abstract base class for one test | Inline Class |
| Stub a validation rule delegate | Inline Delegate |
| Stub a factory function delegate | Inline Delegate |
| Generic interface stub for one test class | Open Generic Interface |
IRepository<T> for multiple types in one test |
Open Generic Interface |
| Generic abstract class stub for one test class | Open Generic Class |
ServiceBase<T> with virtual methods for one test |
Open Generic Class |
This example demonstrates all nine patterns working together in a realistic test scenario.
// STANDALONE PATTERNS (file-based, reusable across tests)
// 1. Standalone Interface: direct instantiation, stub IS implementation
var emailStub = new EmailSvcPatternStub();
emailStub.Send.Call((string to, string subject, string body) => true).Verifiable();
IEmailSvcPattern email = emailStub;
// 2. Generic Standalone Interface: reusable with type args
var notifierStub = new NotifierStub<User>();
notifierStub.Notify.Call((item) => { }).Verifiable();
INotifier<User> notifier = notifierStub;
// 3. Standalone Class: stub wraps instance, use .Object
var serviceBaseStub = new ServiceBaseStub();
serviceBaseStub.Name.Get(() => "TestService").Verifiable();
serviceBaseStub.Execute.Call((cmd) => { }).Verifiable();
ServiceBaseNonGeneric serviceBase = serviceBaseStub.Object;
// 4. Generic Standalone Class: reusable class stub with type args
var repoStub = new RepositoryBaseStub<Product>();
repoStub.GetItem.Call((id) => new Product { Id = id, Name = "Widget" }).Verifiable();
repoStub.Save.Call((entity) => { }).Verifiable();
RepositoryBase<Product> repo = repoStub.Object;
// INLINE PATTERNS (nested within test class)
// 5. Inline Interface: via Stubs namespace
var loggerStub = new CompleteExampleInlineHost.Stubs.ILogSvc();
loggerStub.Log.Call((msg) => { }).Verifiable();
ILogSvc logger = loggerStub;
// 6. Inline Class: use .Object for class instance
var auditStub = new CompleteExampleInlineHost.Stubs.AuditSvcBase();
auditStub.Audit.Call((action) => { }).Verifiable();
AuditSvcBase audit = auditStub.Object;
// 7. Inline Delegate: implicit conversion
var ruleStub = new InlineDelegateTests.Stubs.ValidationRule();
ruleStub.Interceptor.Call((value) => true);
ValidationRule rule = ruleStub;
// 8. Open Generic Interface: inline stub with type args
var processorStub = new CompleteExampleOpenGenericHost.Stubs.IProcessor<Order>();
processorStub.Process.Call((item) => { }).Verifiable();
IProcessor<Order> processor = processorStub;
// 9. Open Generic Class: inline stub with type args, uses .Object
var serviceStub = new CompleteExampleOpenGenericClassHost.Stubs.ServiceBase<Order>();
serviceStub.GetItem.Call((id) => new Order { Id = id }).Verifiable();
ServiceBase<Order> service = serviceStub.Object;- Getting Started - Learn basic stub creation
- Methods Guide - Configure method behavior with Return and Call
- Properties Guide - Work with property interceptors
- Delegates Guide - Stub delegate types for callbacks and validation
- Interceptor API Reference - Complete API documentation
UPDATED: 2026-02-18 (Nine patterns including Standalone Class stubs)