romantitov / MockQueryable

Mocking Entity Framework Core operations such ToListAsync, FirstOrDefaultAsync etc
MIT License
791 stars 77 forks source link

Document usage without mocking framework? #55

Closed natehitze closed 2 years ago

natehitze commented 2 years ago

For simple usage with no customization to the IQueryable<T> mock (such as the "How do I get started" example in the readme) there is no need for a mocking framework to be involved. Using TestAsyncEnumerableEfCore<T> directly is almost 1000x faster which was a very easy performance win for me :). My small test suite is about 15% faster now.

This issue is to request documenting TestAsyncEnumerableEfCore<T> in the readme. I would be happy to write it and submit a PR if that would be acceptable.

Thank you for this package!

Here's the benchmark I used and its results:

using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using MockQueryable.EntityFrameworkCore;
using MockQueryable.Moq;

BenchmarkRunner.Run(typeof(Program).Assembly);

[MemoryDiagnoser]
public class InitializeInstance
{
    private readonly IEnumerable<string> _input;

    public InitializeInstance()
    {
        _input = new[] { "1", "2", "3" };
    }

    [Benchmark(Baseline = true)]
    public IList<string> Moq()
    {
        var mock = _input.AsQueryable().BuildMock();
        return mock.Object.ToList();
    }

    [Benchmark]
    public IList<string> NoMoq()
    {
        return new TestAsyncEnumerableEfCore<string>(_input).ToList();
    }
}

BenchmarkDotNet=v0.13.1, OS=Windows 10.0.22000
Intel Core i9-9900 CPU 3.10GHz, 1 CPU, 16 logical and 8 physical cores
.NET SDK=6.0.201
  [Host]     : .NET 6.0.3 (6.0.322.12309), X64 RyuJIT
  DefaultJob : .NET 6.0.3 (6.0.322.12309), X64 RyuJIT
Method Mean Error StdDev Ratio Gen 0 Gen 1 Allocated
Moq 69,971.94 ns 670.265 ns 594.172 ns 1.000 2.0752 0.9766 17,951 B
NoMoq 70.09 ns 0.647 ns 0.605 ns 0.001 0.0248 - 208 B
romantitov commented 2 years ago

Hello @natehitze. Thank you for your feedback. I'm glad to see so impressive performance improvement. And your benchmark looks very processing. But we also need to take in to account real use cases, and make sure that that it works for test scenarios and for all mock frameworks. If we can use TestAsyncEnumerableEfCore<T> instead of BuildMock() may I ask you just update existing unit tests in MockQueryable.Sample (as an option you can just change implementation of BuildMock extensions with your approach). If will not be any side effects of usage TestAsyncEnumerableEfCore<T> and all tests will be green, I would be happy to include merge your pull request to the repository and update all nuget packages. In this case we even don't need to update documentation. I will also add a special thanks for you to release notes.

natehitze commented 2 years ago

Thanks! I did add a little bit to the README since I'm not sure I explained it very well in this issue but hopefully that change along with the PR description makes more sense.

romantitov commented 2 years ago

Thanks @natehitze for the PR but I expected a bit different changes. In spite of this I will include special thanks for you in the next release notes (release 5.0.2). Based on your suggestion I've made own PR #57 (it takes into account backward compatibility and tested by all existing changes). Unfortunately I cannot merge it to the repo. Thanks for your contribution!