Last active
February 8, 2022 15:35
-
-
Save christothes/7d57db1d16c96669ecd0218ab056a422 to your computer and use it in GitHub Desktop.
Moq extension inspired by https://gist.github.com/7Pass/1c6b329e85ca29071f42. Allows mocks to be setup with all args as default without having to type out each one in the Setup.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static class MoqExtensions | |
{ | |
public static ISetup<T, TResult> SetupDefaultArgs<T, TResult>(this Mock<T> mock, string methodName) | |
where T : class | |
{ | |
var method = typeof(T).GetMethod(methodName); | |
if(method == null) | |
{ | |
throw new ArgumentException($"No method named '{methodName}' exists on type '{typeof(T).Name}'"); | |
} | |
var instance = Expression.Parameter(typeof(T), "m"); | |
var callExp = Expression.Call(instance, method, method.GetParameters().Select(p => GenerateItIsAny(p.ParameterType))); | |
var exp = Expression.Lambda<Func<T, TResult>>(callExp, instance); | |
return mock.Setup(exp); | |
} | |
private static MethodCallExpression GenerateItIsAny(Type T) | |
{ | |
var ItIsAnyT = typeof(It) | |
.GetMethod("IsAny") | |
.MakeGenericMethod(T); | |
return Expression.Call(ItIsAnyT); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void Main() | |
{ | |
var mock = new Mock<IFooContainer>(); | |
mock.SetupDefaultArgs<IFooContainer, string>("DoBar") | |
.Returns<string>((s) => s); | |
var result = mock.Object.DoBar("it worked"); | |
Console.WriteLine(result); | |
mock.SetupDefaultArgs<IFooContainer, string>("DoFoo") | |
.Returns<string, int, Guid>((s, i, g) => $"{s} {i} {g}"); | |
result = mock.Object.DoFoo("it worked", 3, Guid.NewGuid()); | |
Console.WriteLine(result); | |
result = mock.Object.DoFoo("it worked", 3, Guid.NewGuid()); | |
Console.WriteLine(result); | |
// throws "No method named 'Invalid Method' exists on type 'IFooContainer'" | |
mock.SetupDefaultArgs<IFooContainer, string>("Invalid Method") | |
.Returns<string, int, Guid>((s, i, g) => $"{s} {i} {g}"); | |
} | |
public interface IFooContainer | |
{ | |
string DoFoo(string a, int b, Guid id); | |
string DoBar(string a); | |
} |
Nevermind, I found it. It needs a reference to using Moq.Language.Flow;
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Are there certain references that are needed for this? I get an
The non-generic type 'ISetup' cannot be used with type arguments
compiler error from the methodSetupDefaultArgs
.