EasyMoq 0.0.40

There is a newer version of this package available.
See the version list below for details.
dotnet add package EasyMoq --version 0.0.40
NuGet\Install-Package EasyMoq -Version 0.0.40
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="EasyMoq" Version="0.0.40" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add EasyMoq --version 0.0.40
#r "nuget: EasyMoq, 0.0.40"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install EasyMoq as a Cake Addin
#addin nuget:?package=EasyMoq&version=0.0.40

// Install EasyMoq as a Cake Tool
#tool nuget:?package=EasyMoq&version=0.0.40

Build status Nuget

I'm adding more examples and documentation as time permits. If you have specific requests or questions, please ask! 😃

What for?

This tiny, simple to use, and very configurable tool, helps writing unit-tests and integration tests for well structured code, as well as imperfect code, which is based on ICO (dependencies are passed in the constructors).

EasyMoq can take a class, mocks all of its dependencies (as taken in the constructor) recursively (will mock as possible and configured the dependencies of the dependencies) and leave us to write only the code that's really relevant to the test.

How do I use it? (simple example)

If we have the following classes and interfaces:

    public interface IExternalSupplierClass
    {
        string GetDataFromUnreliableSupplier();
    }

    class ExternalSupplierClass : IExternalSupplierClass
    {
        public string GetDataFromUnreliableSupplier()
        {
            return "Get data from unreliable supplier.";
        }
    }

    public interface ILoggerClass
    {
        string LogMessage();
    }

    public class LoggerClass : ILoggerClass
    {
        public string LogMessage()
        {
            return "Logged a message";
        }
    }

    public interface ILibraryClass
    {
        string GetInfoFromExternalSupplierAndDb();
    }

    public class LibraryClass : ILibraryClass
    {
        private readonly IExternalSupplierClass _externalSupplier;
        private readonly ILoggerClass _logger;

        public LibraryClass(IExternalSupplierClass externalSupplier, ILoggerClass logger)
        {
            _externalSupplier = externalSupplier;
            _logger = logger;
        }

        public string GetInfoFromExternalSupplierAndDb()
        {
            return $"Data from supplier: {_externalSupplier.GetDataFromUnreliableSupplier()}";
        }

        public string MethodWeAreNotTestingRightNow()
        {
            return $"Logger message: {_logger.LogMessage()}";
        }
    }

Then normally, in order to test LibraryClass, we would normally do the following:

[Fact]
public void OldWayTest()
{
    var mockDataFromSupplier = "Mocked data from test supplier";
    var expectedResult = $"Data from supplier: {mockDataFromSupplier}";

    var loggerMock = new Mock<ILoggerClass>();
    var externalSupplierClassMock = new Mock<IExternalSupplierClass>();
    externalSupplierClassMock.Setup(x => x.GetDataFromUnreliableSupplier())
        .Returns(() => mockDataFromSupplier);

    var testedService = new LibraryClass(externalSupplierClassMock.Object, loggerMock.Object);

    var result = testedService.GetInfoFromExternalSupplierAndDb();
    result.Should().Be(expectedResult);
}
But instead, with this framework it will be one of following two options:
[Fact]
public void WithEasyMoqTest()
{
    var mockBuilder = new MockBuilder<ILibraryClass, LibraryClass>();

    var mockDataFromSupplier = "Mocked data from test supplier";
    var expectedResult = $"Data from supplier: {mockDataFromSupplier}";

    mockBuilder.GetRelatedMock<IExternalSupplierClass>()
        .Setup(x => x.GetDataFromUnreliableSupplier()).Returns(() => mockDataFromSupplier);

    var result = mockBuilder.GetTestedService().GetInfoFromExternalSupplierAndDb();
    result.Should().Be(expectedResult);
}
public class LibraryClassWithBaseTests : BaseServiceTest<ILibraryClass, LibraryClass>
{
    [Fact]
    public void WithEasyMoqTest()
    {
        var mockDataFromSupplier = "Mocked data from test supplier";
        var expectedResult = $"Data from supplier: {mockDataFromSupplier}";

        GetRelatedMock<IExternalSupplierClass>()
            .Setup(x => x.GetDataFromUnreliableSupplier()).Returns(() => mockDataFromSupplier);

        var result = GetTestedService().GetInfoFromExternalSupplierAndDb();
        result.Should().Be(expectedResult);
    }
}
  • Notice the improvement in readability!
  • Notice the reduction in the number of lines. We went down from 9 lines to 6/7 lines, and this is just with 2 dependencies!

Advantages/features:

  • Saves many lines of code. (See a Simple EasyMoq Example)
  • Makes tests more flexible and durable (since there's no need to fix all the tests when a something like ILogger or IMonitor is added to some constructor) and makes life easier.
  • Enables you to test imperfect code by defaultively leaving the original functionality accessible (examples will be added, for now see tests)
  • Can couple an interface with a class, and by that enable the use any of the class's original functionality through the tested class without mocking or creating anything. Any functionality which is mocked will still use the mock and not the base. (examples will be added, for now see tests)
  • Provides a solution for mocking static dependencies with minimal code change. (will add an example of how to implement soon)
  • 🆕 Added the IntegrationTestMockBuilder class which takes a container, and specific classes/interfaces to mock, and mocks only requested classes/interfaces, while using the normal behaviour of rest of the dependencies. This is intended for usage in integration tests, where we sometimes want to mock just one method which get changing data from the DB or calls an unreliable third party, but still test the rest of the process. (See an example here)
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net45 is compatible.  net451 was computed.  net452 was computed.  net46 was computed.  net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.89 2,009 9/12/2019
0.0.68 580 8/27/2019
0.0.40 674 8/21/2019