Giter Site home page Giter Site logo

serg046 / autofake Goto Github PK

View Code? Open in Web Editor NEW
48.0 5.0 4.0 1.34 MB

Mock any type members including static and non-virtual ones

License: MIT License

C# 100.00%
mock mocking mocking-library fake fake-data faker faker-library testing-tools monkey-patching

autofake's Introduction

AutoFake

Build NuGet NuGet Downloads .NET Framework 4 .NET Standard 2
Telegram Codecov Code Climate Code Climate Code Climate

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);
}

autofake's People

Contributors

dependabot[bot] avatar serg046 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

autofake's Issues

Improve IsAsyncMethod

Try to create AsyncStateMachineAttribute right in the project with the proper namespace

Setting return value based on runtime method arguments or mock instance

Imagine you have the following type:

class SomeType
{
    public SomeType(int someProp) => SomeProp = someProp;
    public int SomeProp { get; }
    public int GetSomeProp(int arg) => SomeProp + arg;
    public SomeMethod(int arg) => Console.WriteLine(GetSomeProp(arg));
}

You might want to do something like this:

var fake = new Fake<SomeType>(5);
sut.Replace(f => f.GetSomeProp(3))
       .If((SomeType instance, object[] arguments) => instance.SomeProp > 0 && arguments.Single() is uint)
       .Return(-1);
sut.Replace(f => f.GetSomeProp(3))
       .If((SomeType instance, object[] arguments) => instance.SomeProp == 2 && !(arguments.Single() is uint))
       .Return(0);

Mock of type constructor

Add ability to mock type constructor because it can run some undesirable actions like database access and so on.

Add Regenerate() method

Since 'Execute()' method runs regeneration of the fake type, it should be indicated.
It needs to introduce a new method and force to use it before the second execution of 'Execute'.

Types from different assemblies should work correctly

  1. Create Type1 in assembly1 and Type2 in assembly2 as dependency of Type1.
  2. Make fake for Type1 and mock anything of Type2
  3. Check that FakeGenerator have access to assembly2 and correctly replace mocked member of Type2.
  4. Modify Type2 as internal and add InternalsVisibleToAttribute to assembly1.
  5. Check step 3. again.

ExpectedCalls(int) implementation

Currently only ExpectedCalls(Func<int, bool>) is supported. Please add support for ExpectedCalls(int) too. The thing is that we cannot simply use something like this:

ExpectedCalls(int number) => ExpectedCalls(x => x == number);

Because that code works only on the client side and cannot be placed inside the library as is.

Force a separate AppDomain when there is a Dispose() call

We use the same AppDomain by defaut. It doesn't allow to unload the generated lib so that we cannot unload it. Please generate an exception if the fake is configured so that it is impossible to place the lib to a seaprate AppDomain.

Apply a mock in scope of fake's type

Support two modes:

  1. Existing mode. Scan all referenced methods of fake's module.
  2. Add mode to scan only methods in fake's type (public/private). It should improve performance. Make it as default mode.

Get rid of GetMonoCecilTypeName/GetClrName

  • Extensions.EquivalentTo
public TypeReference GetType(string fullName, bool runtimeName)
    {
      return !runtimeName ? (TypeReference) this.GetType(fullName) : TypeParser.ParseType(this, fullName);
    }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.