Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Extension methods to quickly ignore arguments without repeating It.IsAny<>()
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);
}
}
}
@joelbyler

This comment has been minimized.

Show comment
Hide comment
@joelbyler

joelbyler Jun 22, 2015

have you tried to submit a pull request to include this yet?

have you tried to submit a pull request to include this yet?

@PandaWood

This comment has been minimized.

Show comment
Hide comment
@PandaWood

PandaWood Dec 3, 2015

Thanks, I found this doesn't work when the mock is called multiple times in the test, subsequent calls fails to return the correct result. I should provide a sample case....

Thanks, I found this doesn't work when the mock is called multiple times in the test, subsequent calls fails to return the correct result. I should provide a sample case....

@aortegadev

This comment has been minimized.

Show comment
Hide comment
@aortegadev

aortegadev Dec 3, 2015

Thanks :) 👍

Thanks :) 👍

@brunoracosta

This comment has been minimized.

Show comment
Hide comment
@brunoracosta

brunoracosta Mar 9, 2016

In my project the VerifyIgnoreArgs does't work because of the line 36 and 46

In my project the VerifyIgnoreArgs does't work because of the line 36 and 46

@kmcc049

This comment has been minimized.

Show comment
Hide comment
@kmcc049

kmcc049 May 25, 2016

Works for me so far, thanks!

kmcc049 commented May 25, 2016

Works for me so far, thanks!

@davidvesely

This comment has been minimized.

Show comment
Hide comment
@davidvesely

davidvesely Jul 7, 2016

It is great. Just had to remove the check at method VisitConstant of class MakeAnyVisitor to allow calls to methods with value type arguments.

It is great. Just had to remove the check at method VisitConstant of class MakeAnyVisitor to allow calls to methods with value type arguments.

@Jacob-McKay

This comment has been minimized.

Show comment
Hide comment
@Jacob-McKay

Jacob-McKay Jul 22, 2016

I would love this if it worked, defining It.IsAny(), It.IsAny(), It.IsAny(), ... is such a PITA

I would love this if it worked, defining It.IsAny(), It.IsAny(), It.IsAny(), ... is such a PITA

@rahulbpatel

This comment has been minimized.

Show comment
Hide comment
@rahulbpatel

rahulbpatel Dec 8, 2017

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.

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.

@Crashdummyy

This comment has been minimized.

Show comment
Hide comment
@Crashdummyy

Crashdummyy Feb 1, 2018

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... )

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... )

@christothes

This comment has been minimized.

Show comment
Hide comment
@christothes

christothes May 25, 2018

I was inspired by your gist and created this variation.

I was inspired by your gist and created this variation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment