I'm trying to test with Moq that a method that has a "params" list is called, but for some reason this is failing. The method signature is something like this :
void AttachAsModifiedToOrders(IOrder order, params
Expression<Func<IOrder, object>>[] modifiedProperties);
Then in the Mock setup i've done something like this to do a simple "remove / insert" from the mocked collection :
MockEntities.Setup(n => n.AttachAsModifiedToOrders(It.IsAny<DataAccess.Order>()))
.Callback<IOrder, Expression<Func<IOrder, object>>[]>((order, expr) =>
{ Orders.Remove(Orders.Where(o => o.Id== order.Id).First());
Orders.Add((DataAccess.Order)order); });
Finally, the verification :
MockEntities.Verify(x => x.AttachAsModifiedToOrders(It.IsAny<Order>(),
It.IsAny<Expression<Func<IOrder, object>>>()), Times.Exactly(1));
I've checked, and the code executes ok and the method is called (the mocked one), but the verification is failing. am i missing something? or is it just that this "params" call is not supported by Moq?
I had difficulty replicating this. I think there's a typo in your verify:
MockEntities.Verify(x => x.AttachAsModifiedToOrders(It.IsAny<Order>(), It.IsAny<Expression<Func<IOrder, object>>>()), Times.Exactly(1));
Should be:
MockEntities.Verify(x => x.AttachAsModifiedToOrders(It.IsAny<Order>(), It.IsAny<Expression<Func<IOrder, object[]>>>()), Times.Exactly(1));
I also wonder if the first It.IsAny should be the interface and not the concrete type?
However, this is a overly-complicated test of some bit of functionality, and the code sample is missing a few pieces, like the DataAccess type or class instance (not sure?), Order, and Orders.
To work around that, I created the IOrder interface and a manipulator object that uses the interface, its a bit nonsensical, but it drives the test:
public interface IOrder
{
void AttachAsModifiedToOrders(IOrder order, params Expression<Func<IOrder, object[]>>[] modifiedProperties);
}
public class Manipulator
{
public Manipulator(IOrder order)
{
Expression<Func<IOrder, object[]>> exp = o => new object[0];
order.AttachAsModifiedToOrders(order, exp);
}
public void DoStuff() { }
}
I then created a test fixture to validate the params arg:
[TestFixture]
public class Tester
{
[Test]
public void Test()
{
var order = new Mock<IOrder>();
order.Setup(n => n.AttachAsModifiedToOrders(It.IsAny<IOrder>()));
var manipulator = new Manipulator(order.Object);
manipulator.DoStuff();
order.Verify(x => x.AttachAsModifiedToOrders(It.IsAny<IOrder>(), It.IsAny<Expression<Func<IOrder, object[]>>>()), Times.Once());
}
}
This works for me, so I don't think the problem is the params value and Moq directly. I do think you'd be well off to take a step back and see if you are really unit testing the class that interacts with the Mock, or trying to verify integrated usages of a couple different types. The params and expression tree is a bit of a smell also.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With