AutoFake
Mock any type members including static and non-virtual ones
Install / Use
/learn @Serg046/AutoFakeREADME
AutoFake
Imagine you have the following Calendar class and you want to replace some members which are not overridable via classic mocking libraries...
public class Calendar
{
public static DateTime Yesterday => DateTime.Now.AddDays(-1);
internal Task<DateTime> AddSomeMinutesAsync(DateTime date) => Task.Run(() => AddSomeMinutes(date));
public static DateTime AddSomeMinutes(DateTime date) => date.AddMinutes(new Random().Next(1, 10));
}
Static DateTime.Now property (run it on .NET Fiddle):
[Fact]
public void Yesterday_SomeDay_ThePrevDay()
{
var fake = new Fake<Calendar>();
var sut = fake.Rewrite(() => Calendar.Yesterday);
sut.Replace(() => DateTime.Now).Return(new DateTime(2016, 8, day: 8));
Assert.Equal(new DateTime(2016, 8, 7), sut.Execute());
}
Non-static and virtual Random.Next(int, int) method but instantiated right inside the AddSomeMinutes method (run it on .NET Fiddle):
[Fact]
public async Task AddSomeMinutesAsync_SomeDay_MinutesAdded()
{
var randomValue = 7;
var date = new DateTime(2016, 8, 8, hour: 0, minute: 0, second: 0);
var fake = new Fake<Calendar>();
var sut = fake.Rewrite(f => f.AddSomeMinutesAsync(date));
sut.Replace((Random r) => r.Next(1, 10)) // Arg.Is<int>(i => i == 10) is also possible
// r.Next(1, 11) fails with "Expected - 11, actual - 10"
.ExpectedCalls(1) // c => c > 1 fails with "Actual value - 1"
.Return(randomValue);
Assert.Equal(date.AddMinutes(randomValue), await sut.Execute());
}
You can also add additional statements at specific places that could be helpful for non-trivial scenarios like race-condition testing (run it on .NET Fiddle):
[Fact]
public void AddSomeMinutes_SomeDay_EventsRecorded()
{
var events = new List<string>();
var fake = new Fake<Calendar>();
var sut = fake.Rewrite(() => Calendar.AddSomeMinutes(new DateTime(2016, 8, 8)));
sut.Prepend(() => events.Add("The first line"));
sut.Prepend(() => events.Add("The line before AddMinutes(...) call"))
.Before((DateTime date) => date.AddMinutes(Arg.IsAny<int>()));
sut.Append(() => events.Add("The line after new Random() call"))
.After(() => new Random());
sut.Append(() => events.Add("The last line"));
sut.Execute();
Assert.Equal(new[]
{
"The first line",
"The line after new Random() call", // indeed, this call is earlier
"The line before AddMinutes(...) call",
"The last line"
},
events);
}
Related Skills
node-connect
347.6kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
108.4kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
347.6kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
347.6kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
