0

I have an issue with Mocking methods Please see below:

This is the interface

public interface IShop
{
    string CheckNames(string[] names);
}

Here is my Mock

var names = "A,B,C";
var shopMock = new Mock<IShop>(MockBehavior.Strict);
shopMock.Setup(s => s.CheckNames(names.Split(','))).Returns("GoodNames");

However when I call this method in my test, this method is failed with Moq.MockException : IShop.CheckNames(["A", "B", "C"]) invocation failed with mock behavior Strict.

var obj = shopMock.Object;
Assert.AreEqual("GoodNames", obj.CheckNames(names.Split(',')));

To make it work, I need to

var names = "A,B,C";
var shopMock = new Mock<IShop>(MockBehavior.Strict);

var nameList = names.Split(',');

shopMock.Setup(s => s.CheckNames(nameList)).Returns("GoodNames");

var obj = shopMock.Object;
Assert.AreEqual("GoodNames", obj.CheckNames(names.Split(',')));

Why I need to create nameList here to make it to work? Thanks

0

1 Answer 1

2

It seems, that in first case test will fail, because two calls of names.Split(',') return different references for result string[] and mock setup and Assert are called with different object. You should use It.Is expression to setup mock accepting any array with A, B, C values for CheckNames in first case

var names = "A,B,C";
            
var shopMock = new Mock<IShop>(MockBehavior.Strict);
shopMock.Setup(s =>
        s.CheckNames(It.Is<string[]>(_ => _.SequenceEqual(names.Split(',', StringSplitOptions.None)))))
    .Returns("GoodNames");
var obj = shopMock.Object;
Assert.Equal("GoodNames", obj.CheckNames(names.Split(',')));

Or use the same array for Setup and Assert methods, which seems to be done in your second case (but full sample is missing)

var names = "A,B,C";
var nameList = names.Split(',');

var shopMock = new Mock<IShop>(MockBehavior.Strict);
shopMock.Setup(s => s.CheckNames(nameList)).Returns("GoodNames");
var obj = shopMock.Object;
Assert.Equal("GoodNames", obj.CheckNames(nameList));
Sign up to request clarification or add additional context in comments.

4 Comments

This is the second case and it works in this way too. var names = "A,B,C"; var shopMock = new Mock<IShop>(MockBehavior.Strict); var list = names.Split(','); shopMock.Setup(s => s.CheckNames(list)).Returns("GoodNames"); var obj = shopMock.Object; Assert.AreEqual("GoodNames", obj.CheckNames(names.Split(',')));
Not sure why it works with Assert.AreEqual("GoodNames", obj.CheckNames(names.Split(','))); if the setup is on a different array object
@Helic which Moq and .NET version are you using? s => s.CheckNames(names.Split(',')) will raise An expression tree may not contain a call or invocation that uses optional arguments error in my end
I am using Moq 4.7.99 and .net 4.6.2.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.