EasyMoq 0.0.40
See the version list below for details.
dotnet add package EasyMoq --version 0.0.40
NuGet\Install-Package EasyMoq -Version 0.0.40
<PackageReference Include="EasyMoq" Version="0.0.40" />
paket add EasyMoq --version 0.0.40
#r "nuget: EasyMoq, 0.0.40"
// 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
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 | Versions 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. |
-
.NETFramework 4.5
- Castle.Windsor (>= 5.0.0)
- Moq (>= 4.12.0)
-
.NETStandard 2.0
- Castle.Windsor (>= 5.0.0)
- Moq (>= 4.12.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.