Skip to main content

Imposter by Bitchiko Tchelidze

NuGet / site data

Nuget GitHub last commit GitHub Repo stars

Details

Info

info

Name: Imposter

Imposter — Source-generated test doubles, zero runtime overhead. A high-performance Roslyn incremental source generator that produces imposters (mocks/stubs) for interfaces and overridable class members via GenerateImposterAttribute. Ships analyzer + runtime in a single package.

Author: Bitchiko Tchelidze

NuGet: https://www.nuget.org/packages/Imposter/

You can find more details at https://github.com/themidnightgospel/Imposter

Source: https://github.com/themidnightgospel/Imposter

Author

note

Bitchiko Tchelidze Alt text

Original Readme

note

Imposter logo

Fast and Memory-Efficient Mocking Library

Build, Test, and Format verification Nuget

Imposter is a mocking library that's using roslyn source generators to achieve high performance and low memory footprint.

Visit the Docs for more information

🚀 Quick Start

Add nuget package reference:

dotnet add package Imposter

Pick an interface or non-sealed class that you would like to generate an imposter for.

Say we have a below interface


namespace Application.Domain;

public interface ICalculator
{
int Add(int a, int b);
}

Use [GenerateImposter] attribute in your tests project, this will generate an imoster

[assembly: GenerateImposter(typeof(Application.Domain.ICalculator))]

Then use can use the generated imposter in your tests

using System.Threading.Tasks;
using Imposter.Abstractions;

// c# 14
var imposter = ICalculator.Imposter();

// c# 9 - 13
// var imposter = new ICalculatorImposter();

imposter.Add(Arg<int>.Any(), Arg<int>.Any())
.Returns(1)
.Then()
.Returns(2);

var calculator = imposter.Instance();

calculator.Add(1, 2); // 1
calculator.Add(1, 2); // 2

Learn more: https://themidnightgospel.github.io/Imposter/

✨ Feature-Rich

⏱️ Benchmark

We benchmarked the simple method-impersonation scenario: we set up a Square method to return input * input and ran it for 1, 10, 100, and 1000 iterations.

public interface ICalculator
{
int Square(int input);
}

Mean execution time

MethodIterationMean
Moq169,346.1 ns
NSubstitute11,976.2 ns
FakItEasy12,006.7 ns
Imposter1194.3 ns
Moq10686,282.9 ns
NSubstitute1011,201.6 ns
FakItEasy1012,399.0 ns
Imposter101,896.7 ns
Moq1006,804,897.3 ns
NSubstitute100335,390.6 ns
FakItEasy100258,220.2 ns
Imposter10034,011.7 ns
Moq100099,710,929.5 ns
NSubstitute100026,986,939.0 ns
FakItEasy100018,997,374.5 ns
Imposter10002,452,970.7 ns

Allocated Memory

MethodIterationAllocated
Moq113.05 KB
NSubstitute17.84 KB
FakeItEasy15.84 KB
Imposter12.4 KB
Moq10115.73 KB
NSubstitute1029.29 KB
FakeItEasy1038.81 KB
Imposter1022.37 KB
Moq1001416.91 KB
NSubstitute100247.26 KB
FakeItEasy1001033.38 KB
Imposter100222.05 KB
Moq100042275.19 KB
NSubstitute10002420.82 KB
FakeItEasy100077101.74 KB
Imposter10002218.93 KB

Benchmark Environment

BenchmarkDotNet v0.15.6, Windows 11 (10.0.26200.6899)
13th Gen Intel Core i9-13900HX 2.20GHz, 1 CPU, 32 logical and 24 physical cores
.NET SDK 10.0.100
[Host] : .NET 8.0.21 (8.0.21, 8.0.2125.47513), X64 RyuJIT x86-64-v3
DefaultJob : .NET 8.0.21 (8.0.21, 8.0.2125.47513), X64 RyuJIT x86-64-v3

See other benchmarks benchmark

Docs

Docs: https://themidnightgospel.github.io/Imposter/

License

Licensed under the MIT License. See LICENSE.txt for details.

About

note

Generate classes from interfaces and allows return of mock data.

Useful for testing and prototyping.

How to use

Example (source csproj, source files)

This is the CSharp Project that references Imposter

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
<PackageReference Include="coverlet.collector" Version="3.2.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\MockData\MockData.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Imposter" Version="0.1.4" />
</ItemGroup>

<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
</PropertyGroup>

</Project>

Generated Files

Those are taken from $(BaseIntermediateOutputPath)\GX

// <auto-generated />
#nullable enable
#pragma warning disable
using global::System;
using global::System.Linq;
using global::System.Collections.Generic;
using global::System.Threading.Tasks;
using global::System.Diagnostics;
using global::System.Runtime.CompilerServices;
using global::Imposter.Abstractions;
using global::System.Collections.Concurrent;

namespace MockData
{
[global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
public sealed class IMyClockImposter : global::Imposter.Abstractions.IHaveImposterInstance<global::MockData.IMyClock>
{
private readonly GetNowMethodImposter _getNowMethodImposter;
private readonly GetUtcNowMethodImposter _getUtcNowMethodImposter;
private readonly GetNowMethodInvocationHistoryCollection _getNowMethodInvocationHistoryCollection = new GetNowMethodInvocationHistoryCollection();
private readonly GetUtcNowMethodInvocationHistoryCollection _getUtcNowMethodInvocationHistoryCollection = new GetUtcNowMethodInvocationHistoryCollection();
public IGetNowMethodImposterBuilder GetNow()
{
return new GetNowMethodImposter.Builder(_getNowMethodImposter, _getNowMethodInvocationHistoryCollection);
}

public IGetUtcNowMethodImposterBuilder GetUtcNow()
{
return new GetUtcNowMethodImposter.Builder(_getUtcNowMethodImposter, _getUtcNowMethodInvocationHistoryCollection);
}

private readonly global::Imposter.Abstractions.ImposterMode _invocationBehavior;
private ImposterTargetInstance _imposterInstance;
global::MockData.IMyClock global::Imposter.Abstractions.IHaveImposterInstance<global::MockData.IMyClock>.Instance()
{
return _imposterInstance;
}

public delegate global::System.DateTime GetNowDelegate();
public delegate void GetNowCallbackDelegate();
public delegate global::System.Exception GetNowExceptionGeneratorDelegate();
[global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
public interface IGetNowMethodInvocationHistory
{
bool Matches();
}

[global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
internal class GetNowMethodInvocationHistory : IGetNowMethodInvocationHistory
{
internal global::System.DateTime? Result;
internal global::System.Exception? Exception;
public GetNowMethodInvocationHistory(global::System.DateTime? Result, global::System.Exception? Exception)
{
this.Result = Result;
this.Exception = Exception;
}

public bool Matches()
{
return true;
}

public override string ToString()
{
return "GetNow(" + "" + ")" + " => " + FormatValue(Result) + (Exception == null ? "" : " threw " + FormatValue(Exception));
}

private static string FormatValue(object? value)
{
return "<" + (value?.ToString() ?? "null") + ">";
}
}

[global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
internal class GetNowMethodInvocationHistoryCollection
{
private readonly global::System.Collections.Concurrent.ConcurrentStack<IGetNowMethodInvocationHistory> _invocationHistory = new global::System.Collections.Concurrent.ConcurrentStack<IGetNowMethodInvocationHistory>();
internal void Add(IGetNowMethodInvocationHistory invocationHistory)
{
_invocationHistory.Push(invocationHistory);
}

internal int Count()
{
return _invocationHistory.Count(it => it.Matches());
}

public override string ToString()
{
return string.Join(Environment.NewLine, _invocationHistory.Select(invocation => invocation.ToString()));
}
}

[global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
class GetNowMethodInvocationImposterGroup
{
internal static GetNowMethodInvocationImposterGroup Default = new GetNowMethodInvocationImposterGroup();
private readonly global::System.Collections.Concurrent.ConcurrentQueue<MethodInvocationImposter> _invocationImposters = new global::System.Collections.Concurrent.ConcurrentQueue<MethodInvocationImposter>();
private MethodInvocationImposter? _lastestInvocationImposter;
public GetNowMethodInvocationImposterGroup()
{
}

internal MethodInvocationImposter AddInvocationImposter()
{
MethodInvocationImposter invocationImposter = new MethodInvocationImposter();
_invocationImposters.Enqueue(invocationImposter);
return invocationImposter;
}

private MethodInvocationImposter? GetInvocationImposter()
{
if (_invocationImposters.TryDequeue(out var invocationImposter))
{
if (!invocationImposter.IsEmpty)
{
_lastestInvocationImposter = invocationImposter;
}

return invocationImposter;
}

return _lastestInvocationImposter;
}

public global::System.DateTime Invoke(global::Imposter.Abstractions.ImposterMode invocationBehavior, string methodDisplayName)
{
var invocationImposter = GetInvocationImposter();
if (invocationImposter == null)
{
if (invocationBehavior == global::Imposter.Abstractions.ImposterMode.Explicit)
{
throw new global::Imposter.Abstractions.MissingImposterException(methodDisplayName);
}

invocationImposter = MethodInvocationImposter.Default;
}

return invocationImposter.Invoke(invocationBehavior, methodDisplayName);
}

[global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
internal class MethodInvocationImposter
{
internal static MethodInvocationImposter Default;
static MethodInvocationImposter()
{
Default = new MethodInvocationImposter();
Default.Returns(DefaultResultGenerator);
}

private GetNowDelegate? _resultGenerator;
private readonly global::System.Collections.Concurrent.ConcurrentQueue<GetNowCallbackDelegate> _callbacks = new global::System.Collections.Concurrent.ConcurrentQueue<GetNowCallbackDelegate>();
internal bool IsEmpty => (_resultGenerator == null) && (_callbacks.Count == 0);

public global::System.DateTime Invoke(global::Imposter.Abstractions.ImposterMode invocationBehavior, string methodDisplayName)
{
if (_resultGenerator == null)
{
if (invocationBehavior == global::Imposter.Abstractions.ImposterMode.Explicit)
{
throw new global::Imposter.Abstractions.MissingImposterException(methodDisplayName);
}

_resultGenerator = DefaultResultGenerator;
}

global::System.DateTime result = _resultGenerator.Invoke();
foreach (var callback in _callbacks)
{
callback();
}

return result;
}

internal void Callback(GetNowCallbackDelegate callback)
{
_callbacks.Enqueue(callback);
}

internal void Returns(GetNowDelegate resultGenerator)
{
_resultGenerator = resultGenerator;
}

internal void Returns(global::System.DateTime value)
{
_resultGenerator = () =>
{
return value;
};
}

internal void Throws(GetNowExceptionGeneratorDelegate exceptionGenerator)
{
_resultGenerator = () =>
{
throw exceptionGenerator();
};
}

internal static global::System.DateTime DefaultResultGenerator()
{
return default !;
}
}
}

[global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
public interface IGetNowMethodInvocationImposterGroupCallback
{
IGetNowMethodInvocationImposterGroupContinuation Callback(GetNowCallbackDelegate callback);
}

[global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
public interface IGetNowMethodInvocationImposterGroupContinuation : IGetNowMethodInvocationImposterGroupCallback
{
IGetNowMethodInvocationImposterGroup Then();
}

[global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
public interface IGetNowMethodInvocationImposterGroup : IGetNowMethodInvocationImposterGroupCallback
{
IGetNowMethodInvocationImposterGroupContinuation Throws<TException>()
where TException : global::System.Exception, new();
IGetNowMethodInvocationImposterGroupContinuation Throws(global::System.Exception exception);
IGetNowMethodInvocationImposterGroupContinuation Throws(GetNowExceptionGeneratorDelegate exceptionGenerator);
IGetNowMethodInvocationImposterGroupContinuation Returns(GetNowDelegate resultGenerator);
IGetNowMethodInvocationImposterGroupContinuation Returns(global::System.DateTime value);
}

[global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
public interface GetNowInvocationVerifier
{
void Called(Count count);
}

[global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
public interface IGetNowMethodImposterBuilder : IGetNowMethodInvocationImposterGroup, IGetNowMethodInvocationImposterGroupCallback, GetNowInvocationVerifier
{
}

[global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
internal class GetNowMethodImposter
{
private readonly global::System.Collections.Concurrent.ConcurrentStack<GetNowMethodInvocationImposterGroup> _invocationImposters = new global::System.Collections.Concurrent.ConcurrentStack<GetNowMethodInvocationImposterGroup>();
private readonly GetNowMethodInvocationHistoryCollection _getNowMethodInvocationHistoryCollection;
private readonly global::Imposter.Abstractions.ImposterMode _invocationBehavior;
public GetNowMethodImposter(GetNowMethodInvocationHistoryCollection _getNowMethodInvocationHistoryCollection, global::Imposter.Abstractions.ImposterMode _invocationBehavior)
{
this._getNowMethodInvocationHistoryCollection = _getNowMethodInvocationHistoryCollection;
this._invocationBehavior = _invocationBehavior;
}

public bool HasMatchingInvocationImposterGroup()
{
return FindMatchingInvocationImposterGroup() != null;
}

private GetNowMethodInvocationImposterGroup? FindMatchingInvocationImposterGroup()
{
if (_invocationImposters.TryPeek(out var invocationImposterGroup))
return invocationImposterGroup;
else
return null;
}

public global::System.DateTime Invoke()
{
var matchingInvocationImposterGroup = FindMatchingInvocationImposterGroup();
if (matchingInvocationImposterGroup == default)
{
if (_invocationBehavior == global::Imposter.Abstractions.ImposterMode.Explicit)
{
throw new global::Imposter.Abstractions.MissingImposterException("DateTime IMyClock.GetNow()");
}

matchingInvocationImposterGroup = GetNowMethodInvocationImposterGroup.Default;
}

try
{
var result = matchingInvocationImposterGroup.Invoke(_invocationBehavior, "DateTime IMyClock.GetNow()");
_getNowMethodInvocationHistoryCollection.Add(new GetNowMethodInvocationHistory(result, default));
return result;
}
catch (global::System.Exception ex)
{
_getNowMethodInvocationHistoryCollection.Add(new GetNowMethodInvocationHistory(default !, ex));
throw;
}
}

[global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
internal class Builder : IGetNowMethodImposterBuilder, IGetNowMethodInvocationImposterGroupContinuation
{
private readonly GetNowMethodImposter _imposter;
private readonly GetNowMethodInvocationHistoryCollection _getNowMethodInvocationHistoryCollection;
private readonly GetNowMethodInvocationImposterGroup _invocationImposterGroup;
private GetNowMethodInvocationImposterGroup.MethodInvocationImposter _currentInvocationImposter;
public Builder(GetNowMethodImposter _imposter, GetNowMethodInvocationHistoryCollection _getNowMethodInvocationHistoryCollection)
{
this._imposter = _imposter;
this._getNowMethodInvocationHistoryCollection = _getNowMethodInvocationHistoryCollection;
this._invocationImposterGroup = new GetNowMethodInvocationImposterGroup();
_imposter._invocationImposters.Push(_invocationImposterGroup);
this._currentInvocationImposter = this._invocationImposterGroup.AddInvocationImposter();
}

IGetNowMethodInvocationImposterGroupContinuation IGetNowMethodInvocationImposterGroup.Throws<TException>()
{
_currentInvocationImposter.Throws(() =>
{
throw new TException();
});
return this;
}

IGetNowMethodInvocationImposterGroupContinuation IGetNowMethodInvocationImposterGroup.Throws(global::System.Exception exception)
{
_currentInvocationImposter.Throws(() =>
{
throw exception;
});
return this;
}

IGetNowMethodInvocationImposterGroupContinuation IGetNowMethodInvocationImposterGroup.Throws(GetNowExceptionGeneratorDelegate exceptionGenerator)
{
_currentInvocationImposter.Throws(() =>
{
throw exceptionGenerator.Invoke();
});
return this;
}

IGetNowMethodInvocationImposterGroupContinuation IGetNowMethodInvocationImposterGroupCallback.Callback(GetNowCallbackDelegate callback)
{
_currentInvocationImposter.Callback(callback);
return this;
}

IGetNowMethodInvocationImposterGroupContinuation IGetNowMethodInvocationImposterGroup.Returns(GetNowDelegate resultGenerator)
{
_currentInvocationImposter.Returns(resultGenerator);
return this;
}

IGetNowMethodInvocationImposterGroupContinuation IGetNowMethodInvocationImposterGroup.Returns(global::System.DateTime value)
{
_currentInvocationImposter.Returns(value);
return this;
}

IGetNowMethodInvocationImposterGroup IGetNowMethodInvocationImposterGroupContinuation.Then()
{
this._currentInvocationImposter = _invocationImposterGroup.AddInvocationImposter();
return this;
}

void GetNowInvocationVerifier.Called(global::Imposter.Abstractions.Count count)
{
var invocationCount = _getNowMethodInvocationHistoryCollection.Count();
if (!count.Matches(invocationCount))
{
throw new global::Imposter.Abstractions.VerificationFailedException(count, invocationCount, _getNowMethodInvocationHistoryCollection.ToString());
}
}
}
}

public delegate global::System.DateTime GetUtcNowDelegate();
public delegate void GetUtcNowCallbackDelegate();
public delegate global::System.Exception GetUtcNowExceptionGeneratorDelegate();
[global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
public interface IGetUtcNowMethodInvocationHistory
{
bool Matches();
}

[global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
internal class GetUtcNowMethodInvocationHistory : IGetUtcNowMethodInvocationHistory
{
internal global::System.DateTime? Result;
internal global::System.Exception? Exception;
public GetUtcNowMethodInvocationHistory(global::System.DateTime? Result, global::System.Exception? Exception)
{
this.Result = Result;
this.Exception = Exception;
}

public bool Matches()
{
return true;
}

public override string ToString()
{
return "GetUtcNow(" + "" + ")" + " => " + FormatValue(Result) + (Exception == null ? "" : " threw " + FormatValue(Exception));
}

private static string FormatValue(object? value)
{
return "<" + (value?.ToString() ?? "null") + ">";
}
}

[global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
internal class GetUtcNowMethodInvocationHistoryCollection
{
private readonly global::System.Collections.Concurrent.ConcurrentStack<IGetUtcNowMethodInvocationHistory> _invocationHistory = new global::System.Collections.Concurrent.ConcurrentStack<IGetUtcNowMethodInvocationHistory>();
internal void Add(IGetUtcNowMethodInvocationHistory invocationHistory)
{
_invocationHistory.Push(invocationHistory);
}

internal int Count()
{
return _invocationHistory.Count(it => it.Matches());
}

public override string ToString()
{
return string.Join(Environment.NewLine, _invocationHistory.Select(invocation => invocation.ToString()));
}
}

[global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
class GetUtcNowMethodInvocationImposterGroup
{
internal static GetUtcNowMethodInvocationImposterGroup Default = new GetUtcNowMethodInvocationImposterGroup();
private readonly global::System.Collections.Concurrent.ConcurrentQueue<MethodInvocationImposter> _invocationImposters = new global::System.Collections.Concurrent.ConcurrentQueue<MethodInvocationImposter>();
private MethodInvocationImposter? _lastestInvocationImposter;
public GetUtcNowMethodInvocationImposterGroup()
{
}

internal MethodInvocationImposter AddInvocationImposter()
{
MethodInvocationImposter invocationImposter = new MethodInvocationImposter();
_invocationImposters.Enqueue(invocationImposter);
return invocationImposter;
}

private MethodInvocationImposter? GetInvocationImposter()
{
if (_invocationImposters.TryDequeue(out var invocationImposter))
{
if (!invocationImposter.IsEmpty)
{
_lastestInvocationImposter = invocationImposter;
}

return invocationImposter;
}

return _lastestInvocationImposter;
}

public global::System.DateTime Invoke(global::Imposter.Abstractions.ImposterMode invocationBehavior, string methodDisplayName)
{
var invocationImposter = GetInvocationImposter();
if (invocationImposter == null)
{
if (invocationBehavior == global::Imposter.Abstractions.ImposterMode.Explicit)
{
throw new global::Imposter.Abstractions.MissingImposterException(methodDisplayName);
}

invocationImposter = MethodInvocationImposter.Default;
}

return invocationImposter.Invoke(invocationBehavior, methodDisplayName);
}

[global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
internal class MethodInvocationImposter
{
internal static MethodInvocationImposter Default;
static MethodInvocationImposter()
{
Default = new MethodInvocationImposter();
Default.Returns(DefaultResultGenerator);
}

private GetUtcNowDelegate? _resultGenerator;
private readonly global::System.Collections.Concurrent.ConcurrentQueue<GetUtcNowCallbackDelegate> _callbacks = new global::System.Collections.Concurrent.ConcurrentQueue<GetUtcNowCallbackDelegate>();
internal bool IsEmpty => (_resultGenerator == null) && (_callbacks.Count == 0);

public global::System.DateTime Invoke(global::Imposter.Abstractions.ImposterMode invocationBehavior, string methodDisplayName)
{
if (_resultGenerator == null)
{
if (invocationBehavior == global::Imposter.Abstractions.ImposterMode.Explicit)
{
throw new global::Imposter.Abstractions.MissingImposterException(methodDisplayName);
}

_resultGenerator = DefaultResultGenerator;
}

global::System.DateTime result = _resultGenerator.Invoke();
foreach (var callback in _callbacks)
{
callback();
}

return result;
}

internal void Callback(GetUtcNowCallbackDelegate callback)
{
_callbacks.Enqueue(callback);
}

internal void Returns(GetUtcNowDelegate resultGenerator)
{
_resultGenerator = resultGenerator;
}

internal void Returns(global::System.DateTime value)
{
_resultGenerator = () =>
{
return value;
};
}

internal void Throws(GetUtcNowExceptionGeneratorDelegate exceptionGenerator)
{
_resultGenerator = () =>
{
throw exceptionGenerator();
};
}

internal static global::System.DateTime DefaultResultGenerator()
{
return default !;
}
}
}

[global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
public interface IGetUtcNowMethodInvocationImposterGroupCallback
{
IGetUtcNowMethodInvocationImposterGroupContinuation Callback(GetUtcNowCallbackDelegate callback);
}

[global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
public interface IGetUtcNowMethodInvocationImposterGroupContinuation : IGetUtcNowMethodInvocationImposterGroupCallback
{
IGetUtcNowMethodInvocationImposterGroup Then();
}

[global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
public interface IGetUtcNowMethodInvocationImposterGroup : IGetUtcNowMethodInvocationImposterGroupCallback
{
IGetUtcNowMethodInvocationImposterGroupContinuation Throws<TException>()
where TException : global::System.Exception, new();
IGetUtcNowMethodInvocationImposterGroupContinuation Throws(global::System.Exception exception);
IGetUtcNowMethodInvocationImposterGroupContinuation Throws(GetUtcNowExceptionGeneratorDelegate exceptionGenerator);
IGetUtcNowMethodInvocationImposterGroupContinuation Returns(GetUtcNowDelegate resultGenerator);
IGetUtcNowMethodInvocationImposterGroupContinuation Returns(global::System.DateTime value);
}

[global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
public interface GetUtcNowInvocationVerifier
{
void Called(Count count);
}

[global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
public interface IGetUtcNowMethodImposterBuilder : IGetUtcNowMethodInvocationImposterGroup, IGetUtcNowMethodInvocationImposterGroupCallback, GetUtcNowInvocationVerifier
{
}

[global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
internal class GetUtcNowMethodImposter
{
private readonly global::System.Collections.Concurrent.ConcurrentStack<GetUtcNowMethodInvocationImposterGroup> _invocationImposters = new global::System.Collections.Concurrent.ConcurrentStack<GetUtcNowMethodInvocationImposterGroup>();
private readonly GetUtcNowMethodInvocationHistoryCollection _getUtcNowMethodInvocationHistoryCollection;
private readonly global::Imposter.Abstractions.ImposterMode _invocationBehavior;
public GetUtcNowMethodImposter(GetUtcNowMethodInvocationHistoryCollection _getUtcNowMethodInvocationHistoryCollection, global::Imposter.Abstractions.ImposterMode _invocationBehavior)
{
this._getUtcNowMethodInvocationHistoryCollection = _getUtcNowMethodInvocationHistoryCollection;
this._invocationBehavior = _invocationBehavior;
}

public bool HasMatchingInvocationImposterGroup()
{
return FindMatchingInvocationImposterGroup() != null;
}

private GetUtcNowMethodInvocationImposterGroup? FindMatchingInvocationImposterGroup()
{
if (_invocationImposters.TryPeek(out var invocationImposterGroup))
return invocationImposterGroup;
else
return null;
}

public global::System.DateTime Invoke()
{
var matchingInvocationImposterGroup = FindMatchingInvocationImposterGroup();
if (matchingInvocationImposterGroup == default)
{
if (_invocationBehavior == global::Imposter.Abstractions.ImposterMode.Explicit)
{
throw new global::Imposter.Abstractions.MissingImposterException("DateTime IMyClock.GetUtcNow()");
}

matchingInvocationImposterGroup = GetUtcNowMethodInvocationImposterGroup.Default;
}

try
{
var result = matchingInvocationImposterGroup.Invoke(_invocationBehavior, "DateTime IMyClock.GetUtcNow()");
_getUtcNowMethodInvocationHistoryCollection.Add(new GetUtcNowMethodInvocationHistory(result, default));
return result;
}
catch (global::System.Exception ex)
{
_getUtcNowMethodInvocationHistoryCollection.Add(new GetUtcNowMethodInvocationHistory(default !, ex));
throw;
}
}

[global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
internal class Builder : IGetUtcNowMethodImposterBuilder, IGetUtcNowMethodInvocationImposterGroupContinuation
{
private readonly GetUtcNowMethodImposter _imposter;
private readonly GetUtcNowMethodInvocationHistoryCollection _getUtcNowMethodInvocationHistoryCollection;
private readonly GetUtcNowMethodInvocationImposterGroup _invocationImposterGroup;
private GetUtcNowMethodInvocationImposterGroup.MethodInvocationImposter _currentInvocationImposter;
public Builder(GetUtcNowMethodImposter _imposter, GetUtcNowMethodInvocationHistoryCollection _getUtcNowMethodInvocationHistoryCollection)
{
this._imposter = _imposter;
this._getUtcNowMethodInvocationHistoryCollection = _getUtcNowMethodInvocationHistoryCollection;
this._invocationImposterGroup = new GetUtcNowMethodInvocationImposterGroup();
_imposter._invocationImposters.Push(_invocationImposterGroup);
this._currentInvocationImposter = this._invocationImposterGroup.AddInvocationImposter();
}

IGetUtcNowMethodInvocationImposterGroupContinuation IGetUtcNowMethodInvocationImposterGroup.Throws<TException>()
{
_currentInvocationImposter.Throws(() =>
{
throw new TException();
});
return this;
}

IGetUtcNowMethodInvocationImposterGroupContinuation IGetUtcNowMethodInvocationImposterGroup.Throws(global::System.Exception exception)
{
_currentInvocationImposter.Throws(() =>
{
throw exception;
});
return this;
}

IGetUtcNowMethodInvocationImposterGroupContinuation IGetUtcNowMethodInvocationImposterGroup.Throws(GetUtcNowExceptionGeneratorDelegate exceptionGenerator)
{
_currentInvocationImposter.Throws(() =>
{
throw exceptionGenerator.Invoke();
});
return this;
}

IGetUtcNowMethodInvocationImposterGroupContinuation IGetUtcNowMethodInvocationImposterGroupCallback.Callback(GetUtcNowCallbackDelegate callback)
{
_currentInvocationImposter.Callback(callback);
return this;
}

IGetUtcNowMethodInvocationImposterGroupContinuation IGetUtcNowMethodInvocationImposterGroup.Returns(GetUtcNowDelegate resultGenerator)
{
_currentInvocationImposter.Returns(resultGenerator);
return this;
}

IGetUtcNowMethodInvocationImposterGroupContinuation IGetUtcNowMethodInvocationImposterGroup.Returns(global::System.DateTime value)
{
_currentInvocationImposter.Returns(value);
return this;
}

IGetUtcNowMethodInvocationImposterGroup IGetUtcNowMethodInvocationImposterGroupContinuation.Then()
{
this._currentInvocationImposter = _invocationImposterGroup.AddInvocationImposter();
return this;
}

void GetUtcNowInvocationVerifier.Called(global::Imposter.Abstractions.Count count)
{
var invocationCount = _getUtcNowMethodInvocationHistoryCollection.Count();
if (!count.Matches(invocationCount))
{
throw new global::Imposter.Abstractions.VerificationFailedException(count, invocationCount, _getUtcNowMethodInvocationHistoryCollection.ToString());
}
}
}
}

public IMyClockImposter(global::Imposter.Abstractions.ImposterMode invocationBehavior = global::Imposter.Abstractions.ImposterMode.Implicit)
{
this._getNowMethodImposter = new GetNowMethodImposter(_getNowMethodInvocationHistoryCollection, invocationBehavior);
this._getUtcNowMethodImposter = new GetUtcNowMethodImposter(_getUtcNowMethodInvocationHistoryCollection, invocationBehavior);
this._imposterInstance = new ImposterTargetInstance(this);
this._invocationBehavior = invocationBehavior;
}

[global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
class ImposterTargetInstance : global::MockData.IMyClock
{
private readonly IMyClockImposter _imposter;
public ImposterTargetInstance(IMyClockImposter _imposter)
{
this._imposter = _imposter;
}

public global::System.DateTime GetNow()
{
return _imposter._getNowMethodImposter.Invoke();
}

public global::System.DateTime GetUtcNow()
{
return _imposter._getUtcNowMethodImposter.Invoke();
}
}
}

[global::System.CodeDom.Compiler.GeneratedCode("Imposter.CodeGenerator", "0.1.4.0")]
public static class IMyClockImposterExtensions
{
extension(global::MockData.IMyClock imposter)
{
public static global::MockData.IMyClockImposter Imposter(global::Imposter.Abstractions.ImposterMode invocationBehavior = global::Imposter.Abstractions.ImposterMode.Implicit) => new global::MockData.IMyClockImposter(invocationBehavior);
}
}
}
#nullable restore
#pragma warning restore

Useful

Download Example (.NET C#)

Share Imposter

https://ignatandrei.github.io/RSCG_Examples/v2/docs/Imposter

Category "Tests" has the following generators:

1 Imposter Nuget GitHub Repo stars 2025-12-13

2 mocklis Nuget GitHub Repo stars 2024-01-03

3 MockMe Nuget GitHub Repo stars 2025-02-10

4 MSTest Nuget GitHub Repo stars 2024-04-04

5 Ridge Nuget GitHub Repo stars 2023-08-20

6 Rocks Nuget GitHub Repo stars 2023-04-16

7 TUnit Nuget GitHub Repo stars 2025-11-08

See category

Tests