-
-
Save ngocvantran/1c6b329e85ca29071f42 to your computer and use it in GitHub Desktop.
| using System; | |
| using System.Linq.Expressions; | |
| using Moq.Language.Flow; | |
| namespace Moq | |
| { | |
| public static class MoqExtensions | |
| { | |
| public static ISetup<T, TResult> SetupIgnoreArgs<T, TResult>(this Mock<T> mock, | |
| Expression<Func<T, TResult>> expression) | |
| where T : class | |
| { | |
| expression = new MakeAnyVisitor().VisitAndConvert( | |
| expression, "SetupIgnoreArgs"); | |
| return mock.Setup(expression); | |
| } | |
| public static ISetup<T> SetupIgnoreArgs<T>(this Mock<T> mock, | |
| Expression<Action<T>> expression) | |
| where T : class | |
| { | |
| expression = new MakeAnyVisitor().VisitAndConvert( | |
| expression, "SetupIgnoreArgs"); | |
| return mock.Setup(expression); | |
| } | |
| public static void VerifyIgnoreArgs<T>(this Mock<T> mock, | |
| Expression<Action<T>> expression, Func<Times> times = null) | |
| where T : class | |
| { | |
| expression = new MakeAnyVisitor().VisitAndConvert( | |
| expression, "VerifyIgnoreArgs"); | |
| mock.Verify(expression, times ?? Times.AtLeastOnce); | |
| } | |
| public static void VerifyIgnoreArgs<T, TResult>(this Mock<T> mock, | |
| Expression<Func<T, TResult>> expression, Func<Times> times = null) | |
| where T : class | |
| { | |
| expression = new MakeAnyVisitor().VisitAndConvert( | |
| expression, "VerifyIgnoreArgs"); | |
| mock.Verify(expression, times ?? Times.AtLeastOnce); | |
| } | |
| private class MakeAnyVisitor : ExpressionVisitor | |
| { | |
| protected override Expression VisitConstant(ConstantExpression node) | |
| { | |
| if (node.Value != null) | |
| return base.VisitConstant(node); | |
| var method = typeof(It) | |
| .GetMethod("IsAny") | |
| .MakeGenericMethod(node.Type); | |
| return Expression.Call(method); | |
| } | |
| } | |
| } | |
| } |
| using System; | |
| using System.Collections; | |
| using System.Collections.Generic; | |
| using Xunit; | |
| namespace Moq | |
| { | |
| public class MoqExtensionsTests | |
| { | |
| [Fact] | |
| public void SetupIgnoreArgs_action_should_ignore_arguments() | |
| { | |
| var mock = new Mock<IDummy>(); | |
| mock | |
| .SetupIgnoreArgs(x => x | |
| .Execute(null, null, null)) | |
| .Verifiable(); | |
| mock.Object.Execute("dummy input", | |
| new[] {"dummy value"}, | |
| new Dictionary<string, object> | |
| { | |
| {"dummy key", new object()}, | |
| }); | |
| mock.Verify(); | |
| } | |
| [Fact] | |
| public void SetupIgnoreArgs_function_should_ignore_arguments() | |
| { | |
| var mock = new Mock<IDummy>(); | |
| mock | |
| .SetupIgnoreArgs(x => x | |
| .Get(null, null, null)) | |
| .Verifiable(); | |
| mock.Object.Get("dummy input", | |
| new[] {"dummy value"}, | |
| new Dictionary<string, object> | |
| { | |
| {"dummy key", new object()}, | |
| }); | |
| mock.Verify(); | |
| } | |
| [Fact] | |
| public void VerifyIgnoreArgs_action_should_ignore_arguments() | |
| { | |
| var mock = new Mock<IDummy>(); | |
| mock.Object.Execute("dummy input", | |
| new[] {"dummy value"}, | |
| new Dictionary<string, object> | |
| { | |
| {"dummy key", new object()}, | |
| }); | |
| mock.VerifyIgnoreArgs(x => x | |
| .Execute(null, null, null)); | |
| } | |
| [Fact] | |
| public void VerifyIgnoreArgs_function_should_ignore_arguments() | |
| { | |
| var mock = new Mock<IDummy>(); | |
| mock.Object.Get("dummy input", | |
| new[] {"dummy value"}, | |
| new Dictionary<string, object> | |
| { | |
| {"dummy key", new object()}, | |
| }); | |
| mock.VerifyIgnoreArgs(x => x | |
| .Get(null, null, null)); | |
| } | |
| public interface IDummy | |
| { | |
| void Execute(string input, IList values, | |
| IDictionary<string, object> settings); | |
| string Get(string input, IList values, | |
| IDictionary<string, object> settings); | |
| } | |
| } | |
| } |
I would love this if it worked, defining It.IsAny(), It.IsAny(), It.IsAny(), ... is such a PITA
Just curious, what is the point of the node.Value != null check on line 53? If you have a method signature like foobar(string, int, string) and called SetupIgnoreArgs(x => x.foobar(null, 0, null)) the int will not be ignored.
Won't work for me ...
In Test:
bool saveCalled = true; bool addCalledAfterSave = false; folderMock.SetupIgnoreArgs(f => f.set_AttributeValue(null, null)) .Callback(() => addCalledAfterSave = saveCalled);
set_AttributeValue (has 4 overloads) is called 3 times yet SetupIgnoreArgs won't get called ( addCalledAfterSave remaining false... )
I was inspired by your gist and created this variation.
What is the license for this gist? Can I use it for a commercial project?
What is the license for this gist? Can I use it for a commercial project?
Sure, do whatever you want with it. See https://gist.github.com/7Pass/1c6b329e85ca29071f42#gistcomment-2600736 which seems to be a better version though.
It is great. Just had to remove the check at method VisitConstant of class MakeAnyVisitor to allow calls to methods with value type arguments.