diff --git a/FastMoq.TestingExample/ExampleTests.cs b/FastMoq.TestingExample/ExampleTests.cs index d59d53b..8b892e9 100644 --- a/FastMoq.TestingExample/ExampleTests.cs +++ b/FastMoq.TestingExample/ExampleTests.cs @@ -1,6 +1,5 @@ using FluentAssertions; using Moq; -using System.Diagnostics.CodeAnalysis; using System.IO.Abstractions; using System.IO.Abstractions.TestingHelpers; using Xunit; @@ -9,10 +8,7 @@ namespace FastMoq.TestingExample { - [SuppressMessage("ReSharper", "PossibleNullReferenceException")] - [SuppressMessage("ReSharper", "AssignNullToNotNullAttribute")] - [SuppressMessage("ReSharper", "AccessToModifiedClosure")] - public class TestClassNormalTestsDefaultBase : TestBase + public class TestClassNormalTestsDefaultBase : MockerTestBase { [Fact] public void Test1() @@ -24,23 +20,19 @@ public void Test1() } } - [SuppressMessage("ReSharper", "PossibleNullReferenceException")] - [SuppressMessage("ReSharper", "AssignNullToNotNullAttribute")] - [SuppressMessage("ReSharper", "AccessToModifiedClosure")] - public class TestClassNormalTestsSetupBase : TestBase + public class TestClassNormalTestsSetupBase : MockerTestBase { public TestClassNormalTestsSetupBase() : base(SetupMocksAction) { } - private static void SetupMocksAction(Mocks mocks) + private static void SetupMocksAction(Mocker mocks) { var iFile = new FileSystem().File; - mocks.Strict = true; - + mocks.Strict = true; // Indicates to use an empty mock instead of predefined IFileSystem (FileSystemMock). mocks.Initialize(mock => mock.Setup(x => x.File).Returns(iFile)); } [Fact] - public void Test1() + public void TestStrict() { Component.FileSystem.Should().NotBeNull(); Component.FileSystem.Should().NotBeOfType(); @@ -49,21 +41,18 @@ public void Test1() } } - [SuppressMessage("ReSharper", "PossibleNullReferenceException")] - [SuppressMessage("ReSharper", "AssignNullToNotNullAttribute")] - [SuppressMessage("ReSharper", "AccessToModifiedClosure")] - public class TestClassNormalTestsFull : TestBase + public class TestClassNormalTestsFull : MockerTestBase { private static bool testEventCalled; public TestClassNormalTestsFull() : base(SetupMocksAction, CreateComponentAction, CreatedComponentAction) => testEventCalled = false; private static void CreatedComponentAction(TestClassNormal? obj) => obj.TestEvent += (_, _) => testEventCalled = true; - private static TestClassNormal CreateComponentAction(Mocks mocks) => new(mocks.GetObject()); + private static TestClassNormal CreateComponentAction(Mocker mocks) => new(mocks.GetObject()); - private static void SetupMocksAction(Mocks mocks) + private static void SetupMocksAction(Mocker mocks) { var mock = new Mock(); var iFile = new FileSystem().File; - mocks.Strict = true; + mocks.Strict = true; // Indicates to use an empty mock instead of predefined IFileSystem (FileSystemMock). mocks.AddMock(mock, true); mocks.Initialize(xMock => xMock.Setup(x => x.File).Returns(iFile)); } diff --git a/FastMoq.TestingExample/TestClassNormal.cs b/FastMoq.TestingExample/TestClassNormal.cs index ba4f635..62df810 100644 --- a/FastMoq.TestingExample/TestClassNormal.cs +++ b/FastMoq.TestingExample/TestClassNormal.cs @@ -5,8 +5,8 @@ namespace FastMoq.TestingExample { public class TestClassNormal : ITestClassNormal { - public event EventHandler TestEvent; - public IFileSystem FileSystem { get; set; } + public event EventHandler? TestEvent; + public IFileSystem? FileSystem { get; set; } public TestClassNormal() { } public TestClassNormal(IFileSystem fileSystem) => FileSystem = fileSystem; public void CallTestEvent() => TestEvent?.Invoke(this, EventArgs.Empty); diff --git a/FastMoq.Tests/InstanceModelTests.cs b/FastMoq.Tests/InstanceModelTests.cs index 27bcbc6..f36042b 100644 --- a/FastMoq.Tests/InstanceModelTests.cs +++ b/FastMoq.Tests/InstanceModelTests.cs @@ -1,12 +1,13 @@ using FluentAssertions; -using Moq; using System; using System.IO.Abstractions; using Xunit; +#pragma warning disable CS8602 +#pragma warning disable CS8625 namespace FastMoq.Tests { - public class InstanceModelTests : TestBase> + public class InstanceModelTests : MockerTestBase> { public InstanceModelTests() : base(mocks => new InstanceModel(mocks1 => new FileSystem())) { diff --git a/FastMoq.Tests/MockModelTests.cs b/FastMoq.Tests/MockModelTests.cs index c408737..b423576 100644 --- a/FastMoq.Tests/MockModelTests.cs +++ b/FastMoq.Tests/MockModelTests.cs @@ -3,10 +3,12 @@ using System; using System.IO.Abstractions; using Xunit; +#pragma warning disable CS8602 +#pragma warning disable CS8625 namespace FastMoq.Tests { - public class MockModelTests : TestBase + public class MockModelTests : MockerTestBase { public MockModelTests() : base(mocks => new MockModel(typeof(IFileSystem), new Mock())) { diff --git a/FastMoq.Tests/MocksTests.cs b/FastMoq.Tests/MocksTests.cs index 4b37fb9..5c3c252 100644 --- a/FastMoq.Tests/MocksTests.cs +++ b/FastMoq.Tests/MocksTests.cs @@ -5,11 +5,10 @@ using System.Diagnostics.CodeAnalysis; using System.IO.Abstractions; using System.IO.Abstractions.TestingHelpers; -using System.Reflection; using System.Runtime; using System.Security.Cryptography; using Xunit; - +#pragma warning disable CS8604 #pragma warning disable CS8602 #pragma warning disable CS8625 @@ -18,7 +17,7 @@ namespace FastMoq.Tests [SuppressMessage("ReSharper", "PossibleNullReferenceException")] [SuppressMessage("ReSharper", "AssignNullToNotNullAttribute")] [SuppressMessage("ReSharper", "AccessToModifiedClosure")] - public class MocksTests : TestBase + public class MocksTests : MockerTestBase { public MocksTests() : base(SetupAction, CreateAction, CreatedAction) { @@ -202,15 +201,15 @@ public void GetObject() public void GetList() { var count = 0; - var numbers = Mocks.GetList(3, () => count++); + var numbers = Mocker.GetList(3, () => count++); numbers.Should().BeEquivalentTo(new List {0, 1, 2}); count = 0; - var strings = Mocks.GetList(3, () => (count++).ToString()); + var strings = Mocker.GetList(3, () => (count++).ToString()); strings.Should().BeEquivalentTo(new List { "0", "1", "2"}); count = 0; - var test = Mocks.GetList(3, () => new TestClassMany(count++)); + var test = Mocker.GetList(3, () => new TestClassMany(count++)); test[0].value.Should().Be(0); test[1].value.Should().Be(1); test[2].value.Should().Be(2); @@ -225,7 +224,6 @@ public void RemoveMock() Mocks.RemoveMock(mock).Should().BeTrue(); Mocks.Contains().Should().BeFalse(); Mocks.RemoveMock(mock).Should().BeFalse(); - } [Fact] @@ -237,8 +235,9 @@ public void AddMock() }; var mockResult = Mocks.AddMock(mock, false); - mockResult.Should().Be(mock); - mockResult.Name.Should().Be("First"); + var mockModel = Mocks.GetMockModel(); + mockResult.Mock.Should().Be(mockModel.Mock); + mockModel.Mock.Name.Should().Be("First"); } [Fact] @@ -249,7 +248,7 @@ public void AddMockDuplicateWithoutOverwrite_ShouldThrowArgumentException() Name = "First" }; - Mocks.AddMock(mock, false).Should().Be(mock); + Mocks.AddMock(mock, false).Mock.Should().Be(mock); Action a = () => Mocks.AddMock(mock, false); a.Should().Throw(); @@ -263,12 +262,12 @@ public void AddMockDuplicateWithOverwrite_ShouldSucceed() Name = "First" }; - var mock1 = Mocks.AddMock(mock, false); + var mock1 = Mocks.AddMock(mock, false).Mock as Mock; mock1.Should().Be(mock); mock1.Name.Should().Be("First"); mock.Name = "test"; - var mock2 = Mocks.AddMock(mock, true); + var mock2 = Mocks.AddMock(mock, true).Mock as Mock; mock2.Should().Be(mock); mock2.Name.Should().Be("test"); @@ -381,14 +380,14 @@ public void FindConstructorByBest() private void CheckConstructorByArgs(object data, bool expected = true) { var constructor = Mocks.FindConstructor(typeof(TestClassNormal), data); - var isValid = Mocks.IsValidConstructor(constructor.Key, data); + var isValid = Mocker.IsValidConstructor(constructor.Key, data); isValid.Should().Be(expected); } private void CheckBestConstructor(object data, bool expected = true) { var constructor = Mocks.FindConstructor(true, typeof(TestClassNormal)); - var isValid = Mocks.IsValidConstructor(constructor.Key, data); + var isValid = Mocker.IsValidConstructor(constructor.Key, data); isValid.Should().Be(expected); } @@ -410,21 +409,21 @@ public void FindConstructor_Exact() public void IsValidConstructor() { var constructor = Mocks.FindConstructor(typeof(TestClassNormal), Mocks.GetObject()); - var isValid = Mocks.IsValidConstructor(constructor.Key, Mocks.GetObject()); + var isValid = Mocker.IsValidConstructor(constructor.Key, Mocks.GetObject()); isValid.Should().BeTrue(); - isValid = Mocks.IsValidConstructor(constructor.Key, Mocks.GetObject(), 12); + isValid = Mocker.IsValidConstructor(constructor.Key, Mocks.GetObject(), 12); isValid.Should().BeFalse(); - isValid = Mocks.IsValidConstructor(constructor.Key, 12); + isValid = Mocker.IsValidConstructor(constructor.Key, 12); isValid.Should().BeFalse(); } - private static Mocks CreateAction(Mocks mocks) => new(); + private static Mocker CreateAction(Mocker mocks) => new(); - private static void CreatedAction(Mocks? component) => component.Should().NotBeNull(); + private static void CreatedAction(Mocker? component) => component.Should().NotBeNull(); - private static void SetupAction(Mocks mocks) + private static void SetupAction(Mocker mocks) { mocks.Initialize(mock => mock.SetupAllProperties()); mocks.Initialize(mock => mock.SetupAllProperties()); diff --git a/FastMoq.Tests/NestedClassTests.cs b/FastMoq.Tests/NestedClassTests.cs index eb7fb82..be44c1d 100644 --- a/FastMoq.Tests/NestedClassTests.cs +++ b/FastMoq.Tests/NestedClassTests.cs @@ -1,18 +1,15 @@ using FluentAssertions; -using System; -using System.Collections.Generic; -using System.Text; using Xunit; namespace FastMoq.Tests { public class NestedClassTests { - private Mocks mocks; + private Mocker mocks; public NestedClassTests() { - mocks = new Mocks(); + mocks = new Mocker(); } [Fact] diff --git a/FastMoq.Tests/TestBaseTests.cs b/FastMoq.Tests/TestBaseTests.cs index 3217f99..dc07667 100644 --- a/FastMoq.Tests/TestBaseTests.cs +++ b/FastMoq.Tests/TestBaseTests.cs @@ -1,10 +1,12 @@ using FluentAssertions; using System; using Xunit; +#pragma warning disable CS8604 +#pragma warning disable CS8602 namespace FastMoq.Tests { - public class TestBaseTests : TestBase + public class TestBaseTests : MockerTestBase { [Fact] public void GetMember() diff --git a/FastMoq/FastMoq.csproj b/FastMoq/FastMoq.csproj index 098c66c..99723e0 100644 --- a/FastMoq/FastMoq.csproj +++ b/FastMoq/FastMoq.csproj @@ -11,7 +11,7 @@ $(Authors) Copyright(c) 2022 Christopher Winland $(AssemblyName) - Easy and fast extension of moq (from moqthis), mocking framework, for mocking and auto injection of classes. + Easy and fast extension of the famous Moq mocking framework for mocking and auto injection of classes. https://github.com/cwinland/FastMoq https://github.com/cwinland/FastMoq git @@ -44,13 +44,18 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + diff --git a/FastMoq/InstanceModel.cs b/FastMoq/InstanceModel.cs index a5374ff..73b51cb 100644 --- a/FastMoq/InstanceModel.cs +++ b/FastMoq/InstanceModel.cs @@ -15,9 +15,9 @@ public class InstanceModel : InstanceModel where TClass : class /// Gets or sets the create function. /// /// The create function. - public new Func? CreateFunc + public new Func? CreateFunc { - get => (Func?) base.CreateFunc; + get => (Func?) base.CreateFunc; set => base.CreateFunc = value; } @@ -35,7 +35,7 @@ public InstanceModel() : base(typeof(TClass)) /// Initializes a new instance of the class. /// /// The create function. - public InstanceModel(Func? createFunc) : this() => CreateFunc = createFunc; + public InstanceModel(Func? createFunc) : this() => CreateFunc = createFunc; } /// @@ -57,7 +57,7 @@ public class InstanceModel /// Gets or sets the create function. /// /// The create function. - public Func? CreateFunc { get; internal set; } + public Func? CreateFunc { get; internal set; } #endregion diff --git a/FastMoq/MockModel.cs b/FastMoq/MockModel.cs index 51da0f2..4985550 100644 --- a/FastMoq/MockModel.cs +++ b/FastMoq/MockModel.cs @@ -2,6 +2,23 @@ namespace FastMoq { + public class MockModel : MockModel where T : class + { + public new Mock Mock + { + get => (Mock)base.Mock; + set => base.Mock = value; + } + + internal MockModel(Mock mock) : base(typeof(T), mock) + { + } + + internal MockModel(MockModel mockModel) : base(mockModel.Type, mockModel.Mock) + { + } + } + /// /// Class MockModel. /// diff --git a/FastMoq/Mocks.cs b/FastMoq/Mocker.cs similarity index 77% rename from FastMoq/Mocks.cs rename to FastMoq/Mocker.cs index 5afacdc..84c0292 100644 --- a/FastMoq/Mocks.cs +++ b/FastMoq/Mocker.cs @@ -1,5 +1,4 @@ -using Castle.DynamicProxy.Internal; -using Moq; +using Moq; using System.IO.Abstractions; using System.IO.Abstractions.TestingHelpers; using System.Reflection; @@ -8,76 +7,80 @@ namespace FastMoq { /// - /// Class Mocks. + /// Class Mocks. /// - public class Mocks + public class Mocker { #region Fields /// - /// The file system + /// The file system /// public readonly MockFileSystem fileSystem; /// - /// The mock collection + /// The mock collection /// protected readonly List mockCollection; + /// + /// Gets the type map. + /// + /// The type map. + private readonly Dictionary typeMap; + #endregion #region Properties /// - /// Gets or sets a value indicating whether this is strict. If strict, the mock IFileSystem does not use FileSystemMock and uses Mock of IFileSystem. + /// Gets or sets a value indicating whether this is strict. If strict, the mock IFileSystem does + /// not use FileSystemMock and uses Mock of IFileSystem. /// /// true if strict; otherwise, false. public bool Strict { get; set; } - /// - /// Gets the type map. - /// - /// The type map. - private readonly Dictionary TypeMap; - #endregion /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - public Mocks() + public Mocker() { fileSystem = new(); mockCollection = new(); - TypeMap = new(); + typeMap = new(); } /// /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The type map. - public Mocks(Dictionary typeMap) : this() => TypeMap = typeMap; + public Mocker(Dictionary typeMap) : this() => this.typeMap = typeMap; /// - /// Add specified Mock. + /// Add specified Mock. /// /// Mock Type. /// Mock to Add. - /// Overwrite if the mock exists or throw if this parameter is - /// false. + /// + /// Overwrite if the mock exists or throw if this parameter is + /// false. + /// /// . - public Mock AddMock(Mock mock, bool overwrite) where T : class => (Mock) AddMock(mock, typeof(T), overwrite); + public MockModel AddMock(Mock mock, bool overwrite) where T : class => new(AddMock(mock, typeof(T), overwrite)); /// - /// Adds the type. + /// Adds the type. /// /// The type of the t interface. /// The type of the t class. /// The create function. /// Must be different types. /// - public void AddType(Func? createFunc = null) where TInterface : class where TClass : class, new() + public void AddType(Func? createFunc = null) + where TInterface : class where TClass : class, new() { if (typeof(TInterface) == typeof(TClass)) { @@ -94,18 +97,18 @@ public Mocks() throw new ArgumentException($"{typeof(TClass).Name} cannot be an interface."); } - TypeMap.Add(typeof(TInterface), new InstanceModel(createFunc)); + typeMap.Add(typeof(TInterface), new InstanceModel(createFunc)); } /// - /// Determines whether this instance contains the object. + /// Determines whether this instance contains the object. /// /// /// true if [contains]; otherwise, false. public bool Contains() where T : class => Contains(typeof(T)); /// - /// Determines whether this instance contains the object. + /// Determines whether this instance contains the object. /// /// The type. /// true if [contains] [the specified type]; otherwise, false. @@ -117,7 +120,7 @@ public bool Contains(Type type) => mockCollection.Any(x => x.Type == type); /// - /// Creates the instance. + /// Creates the instance. /// /// /// if set to true [use predefined file system]. @@ -134,7 +137,7 @@ public bool Contains(Type type) => if (type.CreateFunc != null) { - return (T)type.CreateFunc.Invoke(this); + return (T) type.CreateFunc.Invoke(this); } KeyValuePair> constructor = @@ -144,7 +147,7 @@ public bool Contains(Type type) => } /// - /// Creates the mock. + /// Creates the mock. /// /// The type. /// . @@ -169,19 +172,19 @@ public List CreateMock(Type type) throw new ApplicationException("Cannot create instance."); } - AddMock(oMock, type, false); + AddMock(oMock, type); return mockCollection; } /// - /// Creates the mock. + /// Creates the mock. /// /// /// . public List CreateMock() where T : class => CreateMock(typeof(T)); /// - /// Gets the list. + /// Gets the list. /// /// /// The count. @@ -203,14 +206,14 @@ public static List GetList(int count, Func? func) } /// - /// Gets the mock and creates it if necessary. + /// Gets the mock and creates it if necessary. /// /// of Class. /// . - public Mock GetMock() where T : class => (Mock)GetMock(typeof(T)); + public Mock GetMock() where T : class => (Mock) GetMock(typeof(T)); /// - /// Gets the mock. + /// Gets the mock. /// /// The type. /// Mock. @@ -225,10 +228,12 @@ public Mock GetMock(Type type) } /// - /// Gets the object for the given object. + /// Gets the object for the given object. /// /// The information. - /// + /// + /// + /// public object? GetObject(ParameterInfo info) { try @@ -242,7 +247,7 @@ public Mock GetMock(Type type) } /// - /// Gets the object. + /// Gets the object. /// /// The type. /// . @@ -271,14 +276,14 @@ public Mock GetMock(Type type) } /// - /// Gets the object. + /// Gets the object. /// /// /// T. public T? GetObject() where T : class => GetObject(typeof(T)) as T; /// - /// Gets the required mock. + /// Gets the required mock. /// /// The type. /// Mock. @@ -294,14 +299,14 @@ public Mock GetRequiredMock(Type type) } /// - /// Gets the required mock. + /// Gets the required mock. /// /// /// Mock<T>. public Mock GetRequiredMock() where T : class => (Mock) GetRequiredMock(typeof(T)); /// - /// Initializes the specified action. + /// Initializes the specified action. /// /// /// The action. @@ -317,28 +322,29 @@ public Mock Initialize(Action> action) where T : class } /// - /// Remove specified Mock. + /// Remove specified Mock. /// /// Mock Type. /// Mock to Remove. /// true if XXXX, false otherwise. public bool RemoveMock(Mock mock) where T : class { - var mockModel = GetMockModel(typeof(T), mock); + var mockModel = mockCollection.FirstOrDefault(x => x.Type == typeof(T) && x.Mock == mock); + return mockModel != null && mockCollection.Remove(mockModel); } - internal MockModel? GetMockModel(Type type, Mock? mock = null) => mockCollection.FirstOrDefault(x => x.Type == type && (x.Mock == mock || mock == null)); - /// - /// Add specified Mock. Internal API only. + /// Add specified Mock. Internal API only. /// /// Mock to Add. /// Type of Mock. - /// Overwrite if the mock exists or throw if this parameter is - /// false. + /// + /// Overwrite if the mock exists or throw if this parameter is + /// false. + /// /// . - internal Mock AddMock(Mock mock, Type type, bool overwrite) + internal MockModel AddMock(Mock mock, Type type, bool overwrite = false) { if (mock == null) { @@ -357,18 +363,18 @@ internal Mock AddMock(Mock mock, Type type, bool overwrite) ThrowAlreadyExists(mock.GetType()); } - var mockModel = GetMockModel(type) ?? new MockModel(type, mock); + var mockModel = GetMockModel(type); mockModel.Mock = mock; - return GetMock(type); + return GetMockModel(type); } mockCollection.Add(new MockModel(type, mock)); - return GetMock(type); + return GetMockModel(type); } /// - /// Finds the constructor matching args EXACTLY with the same sequence and type. + /// Finds the constructor matching args EXACTLY. /// /// The type. /// The arguments. @@ -379,10 +385,7 @@ internal Mock AddMock(Mock mock, Type type, bool overwrite) Dictionary> allConstructors = GetConstructors(type, args); List>> constructors = allConstructors - .Where(x => x.Value - .Select(z => z?.GetType()) - .SequenceEqual(args.Select(y => y?.GetType()))) - .ToList(); + .Where(x => x.Value.Select(z => z?.GetType()).SequenceEqual(args.Select(y => y?.GetType()))).ToList(); return !constructors.Any() ? throw new NotImplementedException("Unable to find the constructor.") @@ -390,7 +393,7 @@ internal Mock AddMock(Mock mock, Type type, bool overwrite) } /// - /// Finds the constructor and chooses the one with the parameters, if it exists. + /// Finds the constructor. /// /// if set to true [best guess]. /// The type. @@ -422,16 +425,26 @@ internal Mock AddMock(Mock mock, Type type, bool overwrite) /// The type. /// Optional arguments. /// . - internal Dictionary> GetConstructors(Type type, params object?[] instanceParameterValues) => + internal Dictionary> + GetConstructors(Type type, params object?[] instanceParameterValues) => type.GetConstructors() .Where(x => IsValidConstructor(x, instanceParameterValues)) .OrderByDescending(x => x.GetParameters().Length) .ToDictionary(x => x, - y => (instanceParameterValues.Length > 0 ? instanceParameterValues : y.GetParameters().Select(GetObject)).ToList() + y => (instanceParameterValues.Length > 0 ? instanceParameterValues : y.GetParameters().Select(GetObject)) + .ToList() ); internal static object? GetDefaultValue(Type type) => type.IsClass ? null : Activator.CreateInstance(type); + internal MockModel GetMockModel(Type type, Mock? mock = null) => + mockCollection.FirstOrDefault(x => x.Type == type && (x.Mock == mock || mock == null)) ?? + (mock == null ? GetMockModel(type, GetMock(type)) : AddMock(mock, type)); + + internal MockModel GetMockModel(Mock? mock = null) where T : class => new(GetMockModel(typeof(T), mock)); + + internal int GetMockModelIndexOf(Type type) => mockCollection.IndexOf(GetMockModel(type)); + internal InstanceModel GetTypeFromInterface() where T : class { var tType = typeof(T); @@ -441,7 +454,7 @@ internal InstanceModel GetTypeFromInterface() where T : class return new InstanceModel(); } - var mappedType = TypeMap.Where(x => x.Key == typeof(T)).Select(x=>x.Value).FirstOrDefault(); + var mappedType = typeMap.Where(x => x.Key == typeof(T)).Select(x => x.Value).FirstOrDefault(); if (mappedType != null) { @@ -461,9 +474,17 @@ internal InstanceModel GetTypeFromInterface() where T : class ).ToList(); return new InstanceModel(possibleTypes.Count > 1 ? throw new AmbiguousImplementationException() : - !possibleTypes.Any() ? throw new NotImplementedException() : possibleTypes.First()); + !possibleTypes.Any() ? throw new NotImplementedException() : possibleTypes.First() + ); } + internal static bool IsMockFileSystem(bool usePredefinedFileSystem) => usePredefinedFileSystem && + (typeof(T) == typeof(IFileSystem) || + typeof(T) == typeof(FileSystem)); + + internal static bool IsNullableType(Type type) => + type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>); + /// /// Returns true if the argument list == 0 or the types match the constructor exactly. /// @@ -477,7 +498,7 @@ internal static bool IsValidConstructor(ConstructorInfo info, params object?[] i return true; } - var paramList = info.GetParameters().ToList(); + List paramList = info.GetParameters().ToList(); if (instanceParameterValues.Length != paramList.Count) { @@ -490,15 +511,14 @@ internal static bool IsValidConstructor(ConstructorInfo info, params object?[] i { var paramType = paramList[i].ParameterType; var instanceType = instanceParameterValues[i]?.GetType(); - isValid &= (instanceType == null && IsNullableType(paramType)) || (instanceType != null && paramType.IsAssignableFrom(instanceType)); + + isValid &= instanceType == null && IsNullableType(paramType) || + instanceType != null && paramType.IsAssignableFrom(instanceType); } return isValid; - } - internal static bool IsNullableType(Type type) => type.IsGenericType && type.GetGenericTypeDefinition() == typeof (Nullable<>); - internal static bool IsMockFileSystem(bool usePredefinedFileSystem) => usePredefinedFileSystem && (typeof(T) == typeof(IFileSystem) || typeof(T) == typeof(FileSystem)); internal static void ThrowAlreadyExists(Type type) => throw new ArgumentException($"{type} already exists."); } } diff --git a/FastMoq/TestBase.cs b/FastMoq/MockerTestBase.cs similarity index 73% rename from FastMoq/TestBase.cs rename to FastMoq/MockerTestBase.cs index 9577f8a..e2497c5 100644 --- a/FastMoq/TestBase.cs +++ b/FastMoq/MockerTestBase.cs @@ -4,17 +4,17 @@ namespace FastMoq /// Class TestBase. /// /// The type of the t component. - public abstract class TestBase where TComponent : class + public abstract class MockerTestBase where TComponent : class { #region Properties - private Func DefaultCreateAction => _ => Component = Mocks.CreateInstance(); + private Func DefaultCreateAction => _ => Component = Mocks.CreateInstance(); /// /// Gets the mocks. /// /// The mocks. - protected Mocks Mocks { get; } = new(); + protected Mocker Mocks { get; } = new(); /// /// Gets or sets the service. @@ -28,7 +28,7 @@ public abstract class TestBase where TComponent : class /// /// Initializes a new instance of the class with the default createAction. /// - protected TestBase() : this(null, null, null) + protected MockerTestBase() : this(null, null, null) { } @@ -37,7 +37,7 @@ protected TestBase() : this(null, null, null) /// Initializes a new instance of the class with a setup action. /// /// The setup mocks action. - protected TestBase(Action setupMocksAction) : this(setupMocksAction, null) + protected MockerTestBase(Action setupMocksAction) : this(setupMocksAction, null) { } @@ -48,7 +48,7 @@ protected TestBase(Action setupMocksAction) : this(setupMocksAction, null /// /// The create component action. /// The created component action. - protected TestBase(Func createComponentAction, Action? createdComponentAction = null) : this( + protected MockerTestBase(Func createComponentAction, Action? createdComponentAction = null) : this( null, createComponentAction, createdComponentAction @@ -57,12 +57,12 @@ protected TestBase(Func createComponentAction, Action - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The setup mocks action. /// The create component action. /// The created component action. - protected TestBase(Action? setupMocksAction, Func? createComponentAction, + protected MockerTestBase(Action? setupMocksAction, Func? createComponentAction, Action? createdComponentAction = null) { createComponentAction ??= DefaultCreateAction; diff --git a/README.md b/README.md index bd6d1ca..4013df2 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # FastMoq -Easy and fast extension of [Moq](https://github.com/Moq), mocking framework, for mocking and auto injection of classes. +Easy and fast extension of the [Moq](https://github.com/Moq) mocking framework for mocking and auto injection of classes. ## Features @@ -15,16 +15,16 @@ Easy and fast extension of [Moq](https://github.com/Moq), mocking framework, for - .NET 5 - .NET 6 -## Test Base Constructor Parameters - -The following constructor parameters allow customization on the testing classes. +## Available Objects in the FastMoq namespace ```cs -Action setupMocksAction -Func createComponentAction -Action? createdComponentAction +public class Mocker {} +public abstract class MockerTestBase where TComponent : class {} ``` +- Mocker is the primary class for auto mock and injection. This can be used standalone from MockerTestBase. +- MockerTestBase assists in the creation of objects and provides direct access to Mocker. + ## Examples ### Example Test Class @@ -47,7 +47,7 @@ public class TestClassNormal : ITestClassNormal TestClassNormal is created and injects IFileSystem. ```cs -public class TestClassNormalTestsDefaultBase : TestBase +public class TestClassNormalTestsDefaultBase : MockerTestBase { [Fact] public void Test1() @@ -65,11 +65,11 @@ public class TestClassNormalTestsDefaultBase : TestBase TestClassNormal is created and injects IFileSystem. SetupMocksAction creates and configures the Mock IFileSystem before the component is created. ```cs -public class TestClassNormalTestsSetupBase : TestBase +public class TestClassNormalTestsSetupBase : MockerTestBase { public TestClassNormalTestsSetupBase() : base(SetupMocksAction) { } - private static void SetupMocksAction(Mocks mocks) + private static void SetupMocksAction(Mocker mocks) { var iFile = new FileSystem().File; mocks.Strict = true; @@ -93,14 +93,14 @@ public class TestClassNormalTestsSetupBase : TestBase TestClassNormal is created and injects IFileSystem. SetupMocksAction creates and configures the Mock IFileSystem before the component is created. Once created, the CreatedComponentAction subscribes to an event on the component. ```cs -public class TestClassNormalTestsFull : TestBase +public class TestClassNormalTestsFull : MockerTestBase { private static bool testEventCalled; public TestClassNormalTestsFull() : base(SetupMocksAction, CreateComponentAction, CreatedComponentAction) => testEventCalled = false; private static void CreatedComponentAction(TestClassNormal? obj) => obj.TestEvent += (_, _) => testEventCalled = true; - private static TestClassNormal CreateComponentAction(Mocks mocks) => new(mocks.GetObject()); + private static TestClassNormal CreateComponentAction(Mocker mocks) => new(mocks.GetObject()); - private static void SetupMocksAction(Mocks mocks) + private static void SetupMocksAction(Mocker mocks) { var mock = new Mock(); var iFile = new FileSystem().File; @@ -112,7 +112,7 @@ public class TestClassNormalTestsFull : TestBase [Fact] public void Test1() { - Component.FileSystem.Should().Be(Mocks.GetMock().Object); + Component.FileSystem.Should().Be(Mocker.GetMock().Object); Component.FileSystem.Should().NotBeNull(); Component.FileSystem.File.Should().NotBeNull(); Component.FileSystem.Directory.Should().BeNull(); @@ -120,7 +120,7 @@ public class TestClassNormalTestsFull : TestBase Component.CallTestEvent(); testEventCalled.Should().BeTrue(); - Mocks.Initialize(mock => mock.Setup(x => x.Directory).Returns(new FileSystem().Directory)); + Mocker.Initialize(mock => mock.Setup(x => x.Directory).Returns(new FileSystem().Directory)); Component.FileSystem.Directory.Should().NotBeNull(); } @@ -155,13 +155,19 @@ public class TestClassDouble2 : ITestClassDouble {} This code maps ITestClassDouble to TestClassDouble1 when testing a component with ITestClassDouble. ```cs -Mocks.AddType(); +Mocker.AddType(); ``` + + The map also accepts parameters to tell it how to create the instance. ```cs Mocks.AddType(() => new TestClassDouble()); ``` +## Breaking Change + +1.22.604 => Renamed Mocks to Mocker, Renamed TestBase to MockerTestBase. + ## [License - MIT](./License)