diff --git a/NuGet.Config b/NuGet.Config
index a703d7f8..1436d285 100644
--- a/NuGet.Config
+++ b/NuGet.Config
@@ -1,6 +1,9 @@
-
+
+
+
+
diff --git a/src/Moq/Moq.CodeAnalysis/MockNamingConvention.cs b/src/Moq/Moq.CodeAnalysis/MockNamingConvention.cs
index 7b94d1ce..d248dddf 100644
--- a/src/Moq/Moq.CodeAnalysis/MockNamingConvention.cs
+++ b/src/Moq/Moq.CodeAnalysis/MockNamingConvention.cs
@@ -10,13 +10,13 @@ namespace Moq
public class MockNamingConvention : NamingConvention
{
///
- /// Gets the generated code namespace, which is .
+ /// Gets the generated code namespace, which is .
///
- public override string Namespace => MockNaming.Namespace;
+ public override string Namespace => MockNaming.DefaultNamespace;
///
- /// Gets the generated type names suffix, which is .
+ /// Gets the generated type names suffix, which is .
///
- public override string NameSuffix => MockNaming.NameSuffix;
+ public override string NameSuffix => MockNaming.DefaultSuffix;
}
}
diff --git a/src/Moq/Moq.CodeAnalysis/RecursiveMockAnalyzer.cs b/src/Moq/Moq.CodeAnalysis/RecursiveMockAnalyzer.cs
index 8ff96f1c..090fbf3f 100644
--- a/src/Moq/Moq.CodeAnalysis/RecursiveMockAnalyzer.cs
+++ b/src/Moq/Moq.CodeAnalysis/RecursiveMockAnalyzer.cs
@@ -119,7 +119,7 @@ static void ReportDiagnostics(SyntaxNodeAnalysisContext context, INamedTypeSymbo
new Dictionary
{
{ "TargetFullName", name },
- { "Symbols", type.ToFullMetadataName() },
+ { "Symbols", type.ToFullName() },
{ "RecursiveSymbols", "" },
}.ToImmutableDictionary(),
name));
@@ -136,7 +136,7 @@ static void ReportDiagnostics(SyntaxNodeAnalysisContext context, INamedTypeSymbo
new Dictionary
{
{ "TargetFullName", name },
- { "Symbols", type.ToFullMetadataName() },
+ { "Symbols", type.ToFullName() },
{ "RecursiveSymbols", "" },
}.ToImmutableDictionary(),
name));
diff --git a/src/Moq/Moq.CodeFix/MockGenerator.cs b/src/Moq/Moq.CodeFix/MockGenerator.cs
index 44c32d74..c26db199 100644
--- a/src/Moq/Moq.CodeFix/MockGenerator.cs
+++ b/src/Moq/Moq.CodeFix/MockGenerator.cs
@@ -20,7 +20,7 @@ public MockGenerator(NamingConvention naming)
{
new DefaultImports(typeof(LazyInitializer).Namespace, typeof(IMocked).Namespace),
}
- .Concat(GetDefaultProcessors())
+ .Concat(GetDefaultProcessors().Where(p => !(p is FixupImports)))
.Concat(new IDocumentProcessor[]
{
new CSharpMocked(),
diff --git a/src/Moq/Moq.CodeFix/Moq.props b/src/Moq/Moq.CodeFix/Moq.props
index 247880b1..7d8e7109 100644
--- a/src/Moq/Moq.CodeFix/Moq.props
+++ b/src/Moq/Moq.CodeFix/Moq.props
@@ -10,8 +10,8 @@
-
-
+
+
diff --git a/src/Moq/Moq.Sdk.Tests/Fakes.cs b/src/Moq/Moq.Sdk.Tests/Fakes.cs
index f0481445..26e74c38 100644
--- a/src/Moq/Moq.Sdk.Tests/Fakes.cs
+++ b/src/Moq/Moq.Sdk.Tests/Fakes.cs
@@ -42,7 +42,7 @@ public class FakeSetup : IMockSetup
public class FakeInvocation : IMethodInvocation
{
public FakeInvocation() => Target = new Mocked();
-
+
public IArgumentCollection Arguments { get; set; }
public IDictionary Context { get; set; }
@@ -51,6 +51,8 @@ public class FakeInvocation : IMethodInvocation
public object Target { get; set; }
+ public HashSet SkipBehaviors { get; } = new HashSet();
+
public IMethodReturn CreateExceptionReturn(Exception exception) => new FakeReturn { Exception = exception };
public IMethodReturn CreateValueReturn(object returnValue, params object[] allArguments) => new FakeReturn { ReturnValue = returnValue };
diff --git a/src/Moq/Moq.Sdk.Tests/Moq.Sdk.Tests.csproj b/src/Moq/Moq.Sdk.Tests/Moq.Sdk.Tests.csproj
index 43f4f862..fd13465e 100644
--- a/src/Moq/Moq.Sdk.Tests/Moq.Sdk.Tests.csproj
+++ b/src/Moq/Moq.Sdk.Tests/Moq.Sdk.Tests.csproj
@@ -2,7 +2,7 @@
- net471
+ net472
true
true
@@ -16,6 +16,7 @@
+
diff --git a/src/Moq/Moq.Sdk.Tests/StrictMockBehaviorTests.cs b/src/Moq/Moq.Sdk.Tests/StrictMockBehaviorTests.cs
index 3406a993..156fb534 100644
--- a/src/Moq/Moq.Sdk.Tests/StrictMockBehaviorTests.cs
+++ b/src/Moq/Moq.Sdk.Tests/StrictMockBehaviorTests.cs
@@ -13,19 +13,5 @@ public void AppliesToAllInvocations()
public void ThrowsStrictMockException()
=> Assert.Throws(() =>
new StrictMockBehavior().Execute(new FakeInvocation(), () => throw new NotImplementedException()));
-
- [Fact]
- public void ThrowsIfNullInvocation()
- => Assert.Throws(() =>
- new StrictMockBehavior().Execute(null, () => throw new NotImplementedException()));
-
- [Fact]
- public void DoesNotThrowIfSetupScopeActive()
- {
- using (new SetupScope())
- {
- new StrictMockBehavior().Execute(new FakeInvocation(), () => (m, n) => m.CreateValueReturn(null));
- }
- }
}
}
diff --git a/src/Moq/Moq.Sdk/IMock`1.cs b/src/Moq/Moq.Sdk/IMock`1.cs
index 42aa83ef..5e872ae3 100644
--- a/src/Moq/Moq.Sdk/IMock`1.cs
+++ b/src/Moq/Moq.Sdk/IMock`1.cs
@@ -3,7 +3,7 @@
///
/// Provides introspection information about a mock.
///
- public interface IMock : IMock, IFluentInterface
+ public interface IMock : IMock, IFluentInterface where T : class
{
///
/// The mock object this introspection data belongs to.
diff --git a/src/Moq/Moq.Sdk/MockDecorator`1.cs b/src/Moq/Moq.Sdk/MockDecorator`1.cs
index 9668e051..664e8853 100644
--- a/src/Moq/Moq.Sdk/MockDecorator`1.cs
+++ b/src/Moq/Moq.Sdk/MockDecorator`1.cs
@@ -1,13 +1,9 @@
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using Stunts;
-
-namespace Moq.Sdk
+namespace Moq.Sdk
{
///
/// Decorator implementation over an .
///
- public abstract class MockDecorator : MockDecorator, IMock
+ public abstract class MockDecorator : MockDecorator, IMock where T : class
{
readonly IMock mock;
diff --git a/src/Moq/Moq.Sdk/MockExtensions.cs b/src/Moq/Moq.Sdk/MockExtensions.cs
index 3ae45d36..c60a6126 100644
--- a/src/Moq/Moq.Sdk/MockExtensions.cs
+++ b/src/Moq/Moq.Sdk/MockExtensions.cs
@@ -18,14 +18,14 @@ public static class MockExtensions
///
/// Gets the introspection information for a mocked object instance.
///
- public static IMock AsMock(this T instance)
+ public static IMock AsMock(this T instance) where T : class
=> (instance as IMocked)?.Mock.As(instance) ?? throw new ArgumentException(Strings.TargetNotMock, nameof(instance));
///
/// Clones a mock by creating a new instance of the
/// from and copying its behaviors, invocations and state.
///
- public static IMock Clone(this IMock mock)
+ public static IMock Clone(this IMock mock) where T : class
{
if (!mock.State.TryGetValue
- public static IEnumerable InvocationsFor(this IMock mock, Action action)
+ public static IEnumerable InvocationsFor(this IMock mock, Action action) where T : class
{
using (new SetupScope())
{
@@ -66,7 +66,7 @@ public static IEnumerable InvocationsFor(this IMock moc
/// Gets the invocations performed on the mock so far that match the given
/// setup lambda.
///
- public static IEnumerable InvocationsFor(this IMock mock, Func function)
+ public static IEnumerable InvocationsFor(this IMock mock, Func function) where T : class
{
using (new SetupScope())
{
@@ -76,9 +76,9 @@ public static IEnumerable InvocationsFor(this IMo
}
}
- static IMock As(this IMock mock, T target) => mock == null ? null : new Mock(mock, target);
+ static IMock As(this IMock mock, T target) where T : class => mock == null ? null : new Mock(mock, target);
- class Mock : IMock
+ class Mock : IMock where T : class
{
IMock mock;
diff --git a/src/Moq/Moq.Sdk/MockGeneratorAttribute.cs b/src/Moq/Moq.Sdk/MockGeneratorAttribute.cs
index f9acec5b..ae8b5a59 100644
--- a/src/Moq/Moq.Sdk/MockGeneratorAttribute.cs
+++ b/src/Moq/Moq.Sdk/MockGeneratorAttribute.cs
@@ -6,7 +6,7 @@ namespace Moq
/// Annotates a method that is a factory for mocks, so that a
/// compile-time or design-time generator can generate them ahead of time.
///
- [AttributeUsage(AttributeTargets.Method)]
+ [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor)]
public class MockGeneratorAttribute : Attribute
{
}
diff --git a/src/Moq/Moq.Sdk/MockNaming.cs b/src/Moq/Moq.Sdk/MockNaming.cs
index d6d8192a..baec0740 100644
--- a/src/Moq/Moq.Sdk/MockNaming.cs
+++ b/src/Moq/Moq.Sdk/MockNaming.cs
@@ -1,6 +1,5 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
+using Stunts;
namespace Moq.Sdk
{
@@ -10,29 +9,46 @@ namespace Moq.Sdk
public static class MockNaming
{
///
- /// The namespace where generated mocks are declared.
+ /// The default namespace where generated mocks are declared.
///
- public const string Namespace = "Mocks";
+ public const string DefaultNamespace = "Mocks";
///
- /// The suffix added to mock type names.
+ /// The default suffix added to mock type names.
///
- public const string NameSuffix = "Mock";
+ public const string DefaultSuffix = "Mock";
///
- /// Gets the runtime mock name from its base type and implemented interfaces.
+ /// Gets the runtime mock name from its base type and optional additional
+ /// interfaces, using the .
///
- public static string GetName(Type baseType, Type[] implementedInterfaces)
- {
- Array.Sort(implementedInterfaces, Comparer.Create((x, y) => x.Name.CompareTo(y.Name)));
+ public static string GetName(Type baseType, Type[] additionalInterfaces)
+ => GetName(DefaultSuffix, baseType, additionalInterfaces);
- return baseType.Name + string.Join("", implementedInterfaces.Select(x => x.Name)) + NameSuffix;
- }
+ ///
+ /// Gets the runtime mock name from its base type and optional additional interfaces
+ /// and the given appended to the type name.
+ ///
+ public static string GetName(string suffix, Type baseType, Type[] additionalInterfaces)
+ => StuntNaming.GetName(suffix, baseType, additionalInterfaces);
+
+ ///
+ /// Gets the runtime mock full name from its base type and optional additional interfaces,
+ /// using the and .
+ ///
+ public static string GetFullName(Type baseType, params Type[] additionalInterfaces)
+ => GetFullName(DefaultNamespace, DefaultSuffix, baseType, additionalInterfaces);
+
+ ///
+ /// Gets the runtime mock full name from its base type and implemented interfaces.
+ ///
+ public static string GetFullName(string @namespace, Type baseType, params Type[] additionalInterfaces)
+ => GetFullName(@namespace, DefaultSuffix, baseType, additionalInterfaces);
///
/// Gets the runtime mock full name from its base type and implemented interfaces.
///
- public static string GetFullName(Type baseType, Type[] implementedInterfaces)
- => Namespace + "." + GetName(baseType, implementedInterfaces);
+ public static string GetFullName(string @namespace, string suffix, Type baseType, params Type[] additionalInterfaces)
+ => StuntNaming.GetFullName(@namespace, suffix, baseType, additionalInterfaces);
}
}
\ No newline at end of file
diff --git a/src/Moq/Moq.Sdk/StrictMockBehavior.cs b/src/Moq/Moq.Sdk/StrictMockBehavior.cs
index c0a0c5e7..25641033 100644
--- a/src/Moq/Moq.Sdk/StrictMockBehavior.cs
+++ b/src/Moq/Moq.Sdk/StrictMockBehavior.cs
@@ -10,8 +10,6 @@ namespace Moq.Sdk
///
public class StrictMockBehavior : IStuntBehavior
{
- IStuntBehavior fallback = new DefaultValueBehavior();
-
///
/// Always returns
///
@@ -20,16 +18,6 @@ public class StrictMockBehavior : IStuntBehavior
///
/// Throws .
///
- public IMethodReturn Execute(IMethodInvocation invocation, GetNextBehavior next)
- {
- if (invocation == null) throw new ArgumentNullException(nameof(invocation));
-
- if (!SetupScope.IsActive)
- throw new StrictMockException();
-
- // Otherwise, fallback to returning default values so that
- // the fluent setup API can do its work.
- return fallback.Execute(invocation, next);
- }
+ public IMethodReturn Execute(IMethodInvocation invocation, GetNextBehavior next) => throw new StrictMockException();
}
-}
+}
\ No newline at end of file
diff --git a/src/Moq/Moq.Tests/CallBaseTests.cs b/src/Moq/Moq.Tests/CallBaseTests.cs
new file mode 100644
index 00000000..dfd1b6a9
--- /dev/null
+++ b/src/Moq/Moq.Tests/CallBaseTests.cs
@@ -0,0 +1,82 @@
+using Xunit;
+using Moq.Sdk;
+using Sample;
+
+namespace Moq.Tests
+{
+ public class CallBaseTests
+ {
+ [Fact]
+ public void CallBaseNotCalled()
+ {
+ var mock = Mock.Of();
+
+ mock.TurnOn();
+
+ Assert.False(mock.TurnOnCalled);
+ }
+
+ [Fact]
+ public void CallBaseCalledForMockConfig()
+ {
+ var mock = Mock.Of().CallBase();
+
+ mock.TurnOn();
+
+ Assert.True(mock.TurnOnCalled);
+ }
+
+ [Fact]
+ public void CallBaseCalledForInvocationConfig()
+ {
+ var mock = Mock.Of();
+
+ mock.Setup(x => x.TurnOn()).CallBase();
+
+ mock.TurnOn();
+
+ Assert.True(mock.TurnOnCalled);
+ }
+
+ [Fact]
+ public void ThrowsForStrictMockAndMissingSetup()
+ {
+ // Configure CallBase at the Mock level
+ var mock = Mock.Of(MockBehavior.Strict).CallBase();
+
+ Assert.Throws(() => mock.TurnOn());
+ }
+
+ [Fact]
+ public void CallBaseCalledForStrictMockAndMockConfig()
+ {
+ // Configure CallBase at the Mock level
+ var mock = Mock.Of(MockBehavior.Strict).CallBase();
+
+ mock.Setup(x => x.TurnOn());
+
+ mock.TurnOn();
+
+ Assert.True(mock.TurnOnCalled);
+
+ // And we make sure we throw for other missing setups
+ Assert.Throws(() => mock.Recall(""));
+ }
+
+ [Fact]
+ public void CallBaseCalledForStrickMockAndInvocationConfig()
+ {
+ var mock = Mock.Of(MockBehavior.Strict);
+
+ // Configure CallBase at the invocation level
+ mock.Setup(x => x.TurnOn()).CallBase();
+
+ mock.TurnOn();
+
+ Assert.True(mock.TurnOnCalled);
+
+ // And we make sure we throw for other missing setups
+ Assert.Throws(() => mock.Recall(""));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Moq/Moq.Tests/DynamicMock.cs b/src/Moq/Moq.Tests/DynamicMock.cs
index b204c201..2574544f 100644
--- a/src/Moq/Moq.Tests/DynamicMock.cs
+++ b/src/Moq/Moq.Tests/DynamicMock.cs
@@ -11,7 +11,6 @@
namespace Moq
{
- // TODO: can't get Roslyn to compile generated code while running the tests :(
class DynamicMock
{
MockGenerator generator = new MockGenerator();
@@ -34,12 +33,13 @@ async Task GenerateAsync(params Type[] types)
{
var project = await GetProjectAsync();
var compilation = await project.GetCompilationAsync();
- var symbols = types.Select(t => compilation.GetTypeByMetadataName(t.FullName)).ToArray();
+ var symbols = types.Select(t => GetSymbolFromType(compilation, t)).ToArray();
+
var document = await generator.GenerateDocumentAsync(project, symbols, TimeoutToken(5));
var syntax = await document.GetSyntaxRootAsync();
- document = project.AddDocument(MockNaming.GetName(types[0], types.Skip(1).ToArray()) + (language == LanguageNames.CSharp ? ".cs" : ".vb"),
- syntax,
+ document = project.AddDocument(MockNaming.GetName(types[0], types.Skip(1).ToArray()) + (language == LanguageNames.CSharp ? ".cs" : ".vb"),
+ syntax,
filePath: document.FilePath);
await AssertCode.NoErrorsAsync(document);
@@ -61,5 +61,15 @@ async Task GetProjectAsync()
return project;
}
+
+ static ITypeSymbol GetSymbolFromType(Compilation compilation, Type type)
+ {
+ if (!type.IsConstructedGenericType)
+ return compilation.GetTypeByMetadataName(type.FullName);
+
+ return compilation
+ .GetTypeByMetadataName(type.GetGenericTypeDefinition().FullName)
+ .Construct(type.GenericTypeArguments.Select(t => GetSymbolFromType(compilation, t)).ToArray());
+ }
}
}
diff --git a/src/Moq/Moq.Tests/DynamicMockTests.cs b/src/Moq/Moq.Tests/DynamicMockTests.cs
index 5cc9bef6..6050423e 100644
--- a/src/Moq/Moq.Tests/DynamicMockTests.cs
+++ b/src/Moq/Moq.Tests/DynamicMockTests.cs
@@ -1,4 +1,7 @@
-using System.Threading.Tasks;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Sample;
using Stunts;
@@ -24,5 +27,30 @@ public async Task WhenAddingMockBehavior_ThenCanInterceptSelectively()
Assert.Equal(CalculatorMode.Scientific, mode);
Assert.Equal(0, add);
}
+
+ [Fact]
+ public async Task WhenGeneratingGenericMock_ThenImplementsGenericType()
+ {
+ var calculator = await new DynamicMock(LanguageNames.CSharp).CreateAsync>();
+
+ Assert.IsAssignableFrom(calculator);
+ Assert.IsAssignableFrom>(calculator);
+ }
+
+ [Fact]
+ public async Task WhenGeneratingGenericMock_ThenImplementsMultipleGenericType()
+ {
+ var calculator = await new DynamicMock(LanguageNames.CSharp).CreateAsync>>>();
+
+ Assert.IsAssignableFrom(calculator);
+ Assert.IsAssignableFrom>>>(calculator);
+ }
+ }
+
+ public interface IRepository
+ {
+ int Add(T value);
+ bool Delete(int id);
+ T Get(int id);
}
}
\ No newline at end of file
diff --git a/src/Moq/Moq.Tests/LegacyTests.cs b/src/Moq/Moq.Tests/LegacyTests.cs
new file mode 100644
index 00000000..0773264c
--- /dev/null
+++ b/src/Moq/Moq.Tests/LegacyTests.cs
@@ -0,0 +1,28 @@
+using System;
+using Xunit;
+
+namespace Moq.Tests
+{
+ public class LegacyTests
+ {
+ [Fact]
+ public void AsInterface()
+ {
+ var sp = new Mock();
+
+ sp.Setup(x => x.GetService(typeof(IDisposable))).Returns(Mock.Of());
+
+ sp.As()
+ .Setup(x => x.Dispose())
+ .Callback(() => Assert.False(true, "Callback"));
+
+ Assert.NotNull(sp.Object.GetService(typeof(IDisposable)));
+
+ var disposable = sp.Object as IDisposable;
+
+ Assert.NotNull(disposable);
+
+ disposable.Dispose();
+ }
+ }
+}
diff --git a/src/Moq/Moq.Tests/Mocks/CalculatorMock.cs b/src/Moq/Moq.Tests/Mocks/CalculatorMock.cs
new file mode 100644
index 00000000..61ac5237
--- /dev/null
+++ b/src/Moq/Moq.Tests/Mocks/CalculatorMock.cs
@@ -0,0 +1,90 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Diagnostics;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Threading;
+using Moq.Sdk;
+using Sample;
+using Stunts;
+
+namespace Mocks
+{
+ public partial class CalculatorMock : Calculator, IMocked, IStunt
+ {
+ BehaviorPipeline pipeline = new BehaviorPipeline();
+
+ public ObservableCollection Behaviors => pipeline.Behaviors;
+
+ public override event EventHandler TurnedOn
+ {
+ add => pipeline.Execute(new MethodInvocation(this, MethodBase.GetCurrentMethod(), value), (m, n) => { base.TurnedOn += value; return m.CreateValueReturn(null, value); });
+ remove => pipeline.Execute(new MethodInvocation(this, MethodBase.GetCurrentMethod(), value), (m, n) => { base.TurnedOn -= value; return m.CreateValueReturn(null, value); });
+ }
+
+ public override CalculatorMode Mode
+ {
+ get => pipeline.Execute(new MethodInvocation(this, MethodBase.GetCurrentMethod()), (m, n) => m.CreateValueReturn(base.Mode));
+ set => pipeline.Invoke(new MethodInvocation(this, MethodBase.GetCurrentMethod(), value), (m, n) => { base.Mode = value; return m.CreateValueReturn(null, value); });
+ }
+
+ public override int? this[string name]
+ {
+ get => pipeline.Execute(new MethodInvocation(this, MethodBase.GetCurrentMethod()), (m, n) => m.CreateValueReturn(base[name]));
+ set => pipeline.Execute(new MethodInvocation(this, MethodBase.GetCurrentMethod(), name, value), (m, n) => { base[name] = value; return m.CreateValueReturn(null, value); });
+ }
+
+ public override bool IsOn => pipeline.Execute(new MethodInvocation(this, MethodBase.GetCurrentMethod()), (m, n) => m.CreateValueReturn(base.IsOn));
+
+ public override int Add(int x, int y) =>
+ pipeline.Execute(new MethodInvocation(this, MethodBase.GetCurrentMethod(), x, y), (m, n) => m.CreateValueReturn(base.Add(x, y), x, y));
+
+ public override int Add(int x, int y, int z) =>
+ pipeline.Execute(new MethodInvocation(this, MethodBase.GetCurrentMethod(), x, y, z), (m, n) => m.CreateValueReturn(base.Add(x, y, z), x, y, z));
+
+ public override bool TryAdd(ref int x, ref int y, out int z)
+ {
+ z = default(int);
+ var local_x = x;
+ var local_y = y;
+ var local_z = z;
+
+ var result = pipeline.Invoke(new MethodInvocation(this, MethodBase.GetCurrentMethod(), x, y, z),
+ (m, n) => m.CreateValueReturn(base.TryAdd(ref local_x, ref local_y, out local_z), local_x, local_y, local_z), true);
+
+ x = (int)result.Outputs["x"];
+ y = (int)result.Outputs["y"];
+ z = (int)result.Outputs["z"];
+
+ return (bool)result.ReturnValue;
+ }
+
+ public override void TurnOn() =>
+ pipeline.Execute(new MethodInvocation(this, MethodBase.GetCurrentMethod()), (m, n) => { base.TurnOn(); return m.CreateValueReturn(null); });
+
+ public override void Store(string name, int value) =>
+ pipeline.Execute(new MethodInvocation(this, MethodBase.GetCurrentMethod(), name, value), (m, n) => { base.Store(name, value); return m.CreateValueReturn(null, name, value); });
+
+ public override int? Recall(string name) =>
+ pipeline.Execute(new MethodInvocation(this, MethodBase.GetCurrentMethod(), name), (m, n) => m.CreateValueReturn(base.Recall(name), name));
+
+ public override void Clear(string name) =>
+ pipeline.Execute(new MethodInvocation(this, MethodBase.GetCurrentMethod(), name), (m, n) => { base.Clear(name); return m.CreateValueReturn(null, name); });
+
+ public override ICalculatorMemory Memory
+ {
+ get => pipeline.Execute(new MethodInvocation(this, MethodBase.GetCurrentMethod()), (m, n) => m.CreateValueReturn(base.Memory));
+ }
+
+ #region IMocked
+ [DebuggerBrowsable(DebuggerBrowsableState.Never)]
+ IMock mock;
+
+ [DebuggerDisplay("Invocations = {Invocations.Count}", Name = nameof(IMocked.Mock))]
+ [DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
+ [CompilerGenerated]
+ IMock IMocked.Mock => LazyInitializer.EnsureInitialized(ref mock, () => new DefaultMock(this));
+ #endregion
+ }
+}
diff --git a/src/Moq/Moq.Tests/Moq.Tests.csproj b/src/Moq/Moq.Tests/Moq.Tests.csproj
index b403c7ba..2626132a 100644
--- a/src/Moq/Moq.Tests/Moq.Tests.csproj
+++ b/src/Moq/Moq.Tests/Moq.Tests.csproj
@@ -1,7 +1,8 @@
+
- net471
+ net472
true
true
@@ -9,9 +10,11 @@
false
+
+
@@ -23,11 +26,21 @@
+
+
+
+
+
+
+
+
+
+
@@ -37,5 +50,10 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Moq/Moq.Tests/MoqTests.cs b/src/Moq/Moq.Tests/MoqTests.cs
index 4e94c9e5..5f5a6185 100644
--- a/src/Moq/Moq.Tests/MoqTests.cs
+++ b/src/Moq/Moq.Tests/MoqTests.cs
@@ -5,7 +5,6 @@
using static Moq.Syntax;
using Stunts;
using Sample;
-using System.Linq;
using Xunit.Abstractions;
namespace Moq.Tests
@@ -16,6 +15,16 @@ public class MoqTests
public MoqTests(ITestOutputHelper output) => this.output = output;
+ [Fact]
+ public void SetupDoesNotRecordCalls()
+ {
+ var calculator = Mock.Of();
+
+ calculator.Setup(c => c.TurnOn());
+
+ Assert.Empty(calculator.AsMock().Invocations);
+ }
+
[Fact]
public void CanRaiseEvents()
{
@@ -264,7 +273,7 @@ public void CanSetupPropertyWithValueForStrictMock()
{
var calculator = Mock.Of(MockBehavior.Strict);
- calculator.Setup(c => c.Mode = CalculatorMode.Scientific);
+ calculator.Setup(c => c.Mode).Returns(CalculatorMode.Scientific);
var mode = calculator.Mode;
diff --git a/src/Moq/Moq.Tests/RefOutTests.cs b/src/Moq/Moq.Tests/RefOutTests.cs
index 2433bd52..0a11b83a 100644
--- a/src/Moq/Moq.Tests/RefOutTests.cs
+++ b/src/Moq/Moq.Tests/RefOutTests.cs
@@ -718,7 +718,9 @@ async Task ApplyCodeFixAsync(string language, string initial, string expected, b
var doc = project.AddDocument("code.cs", SourceText.From(code));
var compilation = await doc.Project.GetCompilationAsync(TimeoutToken(4));
var diagnostic = compilation.GetDiagnostics(TimeoutToken(5))
- .First(d => provider.FixableDiagnosticIds.Any(fixable => d.Id == fixable));
+ .FirstOrDefault(d => provider.FixableDiagnosticIds.Any(fixable => d.Id == fixable));
+
+ Assert.True(diagnostic != null, $"Could not find any diagnostics with IDs {string.Join(", ", provider.FixableDiagnosticIds)}");
var actions = new List();
var context = new CodeFixContext(doc, diagnostic, (a, d) => actions.Add(a), TimeoutToken(5));
diff --git a/src/Moq/Moq.Tests/VerificationTests.cs b/src/Moq/Moq.Tests/VerificationTests.cs
index 44bb632d..5934a2d9 100644
--- a/src/Moq/Moq.Tests/VerificationTests.cs
+++ b/src/Moq/Moq.Tests/VerificationTests.cs
@@ -222,8 +222,6 @@ public void VerifyExtensionAction()
Assert.Throws(() => calculator.Verify(x => x.TurnOn(), "Should have been called!"));
// Once with message
Assert.Throws(() => calculator.Verify(x => x.TurnOn(), 1, "Should have been called!"));
- // Times.Once with message
- Assert.Throws(() => calculator.Verify(x => x.TurnOn(), Times.Once, "Should have been called!"));
calculator.TurnOn();
@@ -235,8 +233,6 @@ public void VerifyExtensionAction()
calculator.Verify(x => x.TurnOn(), "Should have been called!");
// Once with message
calculator.Verify(x => x.TurnOn(), 1, "Should have been called!");
- // Times.Once with message
- calculator.Verify(x => x.TurnOn(), Times.Once, "Should have been called!");
}
[Fact]
@@ -253,7 +249,7 @@ public void VerifyExtensionFunction()
// Once with message
Assert.Throws(() => calculator.Verify(x => x.Add(2, 3), 1, "Should have been called!"));
// Times.Once with message
- Assert.Throws(() => calculator.Verify(x => x.Add(2, 3), Times.Once, "Should have been called!"));
+ Assert.Throws(() => calculator.Verify(x => x.Add(2, 3).Once(), "Should have been called!"));
calculator.Add(2, 3);
@@ -266,7 +262,7 @@ public void VerifyExtensionFunction()
// Once with message
calculator.Verify(x => x.Add(2, 3), 1, "Should have been called!");
// Times.Once with message
- calculator.Verify(x => x.Add(2, 3), Times.Once, "Should have been called!");
+ calculator.Verify(x => x.Add(2, 3).Once(), "Should have been called!");
}
//[Fact]
diff --git a/src/Moq/Moq/CallBaseBehavior.cs b/src/Moq/Moq/CallBaseBehavior.cs
new file mode 100644
index 00000000..6c503f25
--- /dev/null
+++ b/src/Moq/Moq/CallBaseBehavior.cs
@@ -0,0 +1,38 @@
+using Stunts;
+using Moq.Sdk;
+using System.Linq;
+using System.ComponentModel;
+
+namespace Moq
+{
+ ///
+ /// A custom behavior to enable calls to the base member virtual implementation.
+ /// See method calls.
+ ///
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public class CallBaseBehavior : IStuntBehavior
+ {
+ ///
+ public bool AppliesTo(IMethodInvocation invocation) => true;
+
+ ///
+ public IMethodReturn Execute(IMethodInvocation invocation, GetNextBehavior next)
+ {
+ // Check if CallBase is configured at the Mock or Invocation level
+ var shouldCallBase = invocation.Target.AsMoq().CallBase || invocation.Context.ContainsKey(nameof(IMoq.CallBase));
+
+ if (shouldCallBase)
+ {
+ // Skip the default value to force the base target member is executed
+ invocation.SkipBehaviors.Add(typeof(DefaultValueBehavior));
+
+ // If there is a matching setup for the current invocation, skip the strict
+ // behavior because CallBase should be called instead
+ if (invocation.Target.AsMock().Behaviors.OfType().Any(x => x.AppliesTo(invocation)))
+ invocation.SkipBehaviors.Add(typeof(StrictMockBehavior));
+ }
+
+ return next().Invoke(invocation, next);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Moq/Moq/CallBaseExtension.cs b/src/Moq/Moq/CallBaseExtension.cs
new file mode 100644
index 00000000..bf1c8141
--- /dev/null
+++ b/src/Moq/Moq/CallBaseExtension.cs
@@ -0,0 +1,39 @@
+using Moq.Sdk;
+using System.ComponentModel;
+
+namespace Moq
+{
+ ///
+ /// Extensions for calling base member virtual implementation.
+ ///
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static class CallBaseExtension
+ {
+ ///
+ /// Specifies to call the base member virtual implementations by default.
+ ///
+ public static T CallBase(this T target)
+ {
+ if (target is IMocked mocked && mocked != null)
+ {
+ // Configure CallBase at the Mock level
+ mocked.AsMoq().CallBase = true;
+ }
+ else if (MockContext.CurrentInvocation != null)
+ {
+ // Configure CallBase at the invocation level
+ MockContext.CurrentInvocation.Target.AsMock().GetPipeline(MockContext.CurrentSetup).Behaviors.Add(new DelegateMockBehavior(
+ (m, i, next) =>
+ {
+ // set CallBase
+ i.Context[nameof(IMoq.CallBase)] = true;
+ return next().Invoke(i.Target.AsMock(), i, next);
+ },
+ nameof(IMoq.CallBase)));
+ }
+ // TODO: else throw?
+
+ return target;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Moq/Moq/ConfigurePipelineBehavior.cs b/src/Moq/Moq/ConfigurePipelineBehavior.cs
new file mode 100644
index 00000000..e7784786
--- /dev/null
+++ b/src/Moq/Moq/ConfigurePipelineBehavior.cs
@@ -0,0 +1,39 @@
+using System.ComponentModel;
+using Moq.Sdk;
+using Stunts;
+
+namespace Moq
+{
+ ///
+ /// Configures the current invocation depending on the
+ /// specified for the mock.
+ ///
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ internal class ConfigurePipelineBehavior : IStuntBehavior
+ {
+ ///
+ /// Always applies to all invocations.
+ ///
+ public bool AppliesTo(IMethodInvocation invocation) => true;
+
+ ///
+ /// Configures the current invocation depending on the
+ /// specified for the mock.
+ ///
+ public IMethodReturn Execute(IMethodInvocation invocation, GetNextBehavior next)
+ {
+ var moq = invocation.Target.AsMoq();
+ if (moq.Behavior != MockBehavior.Strict)
+ {
+ invocation.SkipBehaviors.Add(typeof(StrictMockBehavior));
+ }
+
+ // Ensure the Mock pipeline is always created for the matching setup
+ // We need this to skip the StrictBehavior in the CallBaseBehavior
+ if (SetupScope.IsActive)
+ invocation.Target.AsMock().GetPipeline(MockContext.CurrentSetup);
+
+ return next().Invoke(invocation, next);
+ }
+ }
+}
diff --git a/src/Moq/Moq/Extensions.cs b/src/Moq/Moq/Extensions.cs
index 433feac3..1e56cdf5 100644
--- a/src/Moq/Moq/Extensions.cs
+++ b/src/Moq/Moq/Extensions.cs
@@ -1,6 +1,7 @@
using Stunts;
using System.Reflection;
using System;
+using Moq.Sdk;
namespace Moq
{
@@ -22,5 +23,7 @@ public static bool CanBeIntercepted(this Type type)
!type.FullName.StartsWith(TaskFullName, StringComparison.Ordinal) &&
(type.GetTypeInfo().IsInterface ||
(type.GetTypeInfo().IsClass && !type.GetTypeInfo().IsSealed));
+
+ public static IMoq AsMoq(this T instance) where T : class => new Moq(instance.AsMock());
}
}
diff --git a/src/Moq/Moq/IMoq.cs b/src/Moq/Moq/IMoq.cs
index e5133de2..2ae3bf34 100644
--- a/src/Moq/Moq/IMoq.cs
+++ b/src/Moq/Moq/IMoq.cs
@@ -17,5 +17,11 @@ public interface IMoq : IMock
/// Only available for mocks.
///
DefaultValueProvider DefaultValue { get; set; }
+
+ ///
+ /// Whether the base member virtual implementation will be called for mocked classes if no setup is matched.
+ /// Defaults to .
+ ///
+ bool CallBase { get; set; }
}
-}
+}
\ No newline at end of file
diff --git a/src/Moq/Moq/IMoq`1.cs b/src/Moq/Moq/IMoq`1.cs
index 3d0870cc..2cedd58f 100644
--- a/src/Moq/Moq/IMoq`1.cs
+++ b/src/Moq/Moq/IMoq`1.cs
@@ -5,7 +5,7 @@ namespace Moq
///
/// Provides configuration and introspection information for a mock.
///
- public interface IMoq : IMoq, IMock, IFluentInterface
+ public interface IMoq : IMoq, IMock, IFluentInterface where T : class
{
}
}
diff --git a/src/Moq/Moq/Legacy/It.cs b/src/Moq/Moq/Legacy/It.cs
new file mode 100644
index 00000000..49600e38
--- /dev/null
+++ b/src/Moq/Moq/Legacy/It.cs
@@ -0,0 +1,16 @@
+#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
+using System.ComponentModel;
+using static Moq.Syntax;
+
+namespace Moq
+{
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static class It
+ {
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static T IsAny() => Any();
+ }
+}
+#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
\ No newline at end of file
diff --git a/src/Moq/Moq/Legacy/MockSetup`1.cs b/src/Moq/Moq/Legacy/MockSetup`1.cs
new file mode 100644
index 00000000..8c86e81a
--- /dev/null
+++ b/src/Moq/Moq/Legacy/MockSetup`1.cs
@@ -0,0 +1,179 @@
+#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
+using System;
+using System.ComponentModel;
+using Moq.Sdk;
+
+namespace Moq
+{
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public class MockSetup where TTarget : class
+ {
+ readonly TTarget target;
+ readonly IMock mock;
+ readonly Action action;
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup(TTarget target, IMock mock, Action action)
+ {
+ this.target = target;
+ this.mock = mock;
+ this.action = action;
+ target.Setup(action);
+ }
+
+ #region Callback
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ #endregion
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public void Verifiable() => target.Setup(action).Verifiable();
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Throws(Exception exception)
+ {
+ target.Setup(action).Throws(exception);
+ return this;
+ }
+ }
+}
+#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
\ No newline at end of file
diff --git a/src/Moq/Moq/Legacy/MockSetup`2.cs b/src/Moq/Moq/Legacy/MockSetup`2.cs
new file mode 100644
index 00000000..2f201bee
--- /dev/null
+++ b/src/Moq/Moq/Legacy/MockSetup`2.cs
@@ -0,0 +1,327 @@
+#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
+using System;
+using System.ComponentModel;
+using Moq.Sdk;
+
+namespace Moq
+{
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public class MockSetup where TTarget : class
+ {
+ readonly TTarget target;
+ readonly IMock mock;
+ readonly Func function;
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup(TTarget target, IMock mock, Func function)
+ {
+ this.target = target;
+ this.mock = mock;
+ this.function = function;
+ target.Setup(function);
+ }
+
+ #region Callback
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Callback(Action action)
+ {
+ target.Setup(action).Callback(action);
+ return this;
+ }
+
+ #endregion
+
+ #region Returns
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Returns(Func valueFunction)
+ {
+ target.Setup(function).Returns(valueFunction);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Returns(Func valueFunction)
+ {
+ target.Setup(function).Returns(valueFunction);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Returns(Func valueFunction)
+ {
+ target.Setup(function).Returns(valueFunction);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Returns(Func valueFunction)
+ {
+ target.Setup(function).Returns(valueFunction);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Returns(Func valueFunction)
+ {
+ target.Setup(function).Returns(valueFunction);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Returns(Func valueFunction)
+ {
+ target.Setup(function).Returns(valueFunction);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Returns(Func valueFunction)
+ {
+ target.Setup(function).Returns(valueFunction);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Returns(Func valueFunction)
+ {
+ target.Setup(function).Returns(valueFunction);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Returns(Func valueFunction)
+ {
+ target.Setup(function).Returns(valueFunction);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Returns(Func valueFunction)
+ {
+ target.Setup(function).Returns(valueFunction);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Returns(Func valueFunction)
+ {
+ target.Setup(function).Returns(valueFunction);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Returns(Func valueFunction)
+ {
+ target.Setup(function).Returns(valueFunction);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Returns(Func valueFunction)
+ {
+ target.Setup(function).Returns(valueFunction);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Returns(Func valueFunction)
+ {
+ target.Setup(function).Returns(valueFunction);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Returns(Func valueFunction)
+ {
+ target.Setup(function).Returns(valueFunction);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Returns(Func valueFunction)
+ {
+ target.Setup(function).Returns(valueFunction);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Returns(Func valueFunction)
+ {
+ target.Setup(function).Returns(valueFunction);
+ return this;
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Returns(TResult value)
+ {
+ target.Setup(function).Returns(value);
+ return this;
+ }
+
+ #endregion
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public void Verifiable() => target.Setup(function).Verifiable();
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public MockSetup Throws(Exception exception)
+ {
+ target.Setup(function).Throws(exception);
+ return this;
+ }
+ }
+}
+#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
\ No newline at end of file
diff --git a/src/Moq/Moq/Legacy/Mock`1.Overloads.cs b/src/Moq/Moq/Legacy/Mock`1.Overloads.cs
new file mode 100644
index 00000000..b0f6a105
--- /dev/null
+++ b/src/Moq/Moq/Legacy/Mock`1.Overloads.cs
@@ -0,0 +1,167 @@
+#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
+using System.ComponentModel;
+using System.Reflection;
+
+namespace Moq
+{
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public class Mock : Mock where T : class
+ {
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ [MockGenerator]
+ public Mock() : base(Assembly.GetCallingAssembly(), MockBehavior.Loose) { }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ [MockGenerator]
+ public Mock(params object[] args) : base(Assembly.GetCallingAssembly(), MockBehavior.Loose, args) { }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ [MockGenerator]
+ public Mock(MockBehavior behavior, params object[] args) : base(Assembly.GetCallingAssembly(), behavior, args) { }
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public class Mock : Mock where T : class
+ {
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ [MockGenerator]
+ public Mock() : base(Assembly.GetCallingAssembly(), MockBehavior.Loose) { }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ [MockGenerator]
+ public Mock(params object[] args) : base(Assembly.GetCallingAssembly(), MockBehavior.Loose, args) { }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ [MockGenerator]
+ public Mock(MockBehavior behavior, params object[] args) : base(Assembly.GetCallingAssembly(), behavior, args) { }
+ }
+
+ /// Supports the legacy API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public class Mock : Mock