Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moq - It.IsAny<string>() always returning null

Tags:

What may cause It.IsAny<string>() to return null at every call? Am I incorrect in assuming that it is designed to return a non-null string?

Here's the usage - where the Login method throws an ArgumentNullException for a null 2nd argument (connection string). I was assuming that It.IsAny<string>() would provide a non-null string, which would bypass the ArgumentNullException.

var mockApiHelper = new Mock<ApiHelper>(); mockApiHelper.Setup(m => m.Connect(It.IsAny<string>(),                                     It.IsAny<string>(),                                     It.IsAny<string>()));  var repositoryPlugin = new RepositoryPlugin(mockApiHelper.Object); repositoryPlugin.Login(new CredentialsInfo(), It.IsAny<string>());  Assert.IsTrue(repositoryPlugin.LoggedIn,      "LoggedIn property should be true after the user logs in."); 
like image 678
Jeremy Avatar asked May 23 '11 14:05

Jeremy


2 Answers

Well, It.IsAny<TValue> just returns the result of calling Match<TValue>.Create - which in turn returns default(TValue). That will be null for any reference type.

It's not clear whether you're really calling it on the right object though - shouldn't you be calling it on the mock rather than on the real code?

All the samples I've seen use It.IsAny in the context of a mock.Setup call. Could you give more information about how you're trying to use it?

like image 193
Jon Skeet Avatar answered Sep 22 '22 02:09

Jon Skeet


No, It.IsAny is used to specify in your Setup that ANY string passed will match. You can do your setup so that if your method is called only with a particular string it will return. Consider this:

myMock.Setup(x => x.DoSomething(It.IsAny<string>()).Return(123); myMock.Setup(x => x.DoSomething("SpecialString").Return(456); 

Whatever is using the mock will then get different values depending on the parameter the mock is passed when DoSomething is invoked. You can do the same thing when verifying method calls:

myMock.Verify(x => x.DoSomething(It.IsAny<string>())); // As long as DoSomething was called, this will be fine. myMock.Verify(x => x.DoSomething("SpecialString"));  // DoSomething MUST have been called with "SpecialString" 

Also, I see you edited your question. Instead of:

Assert.IsTrue(repositoryPlugin.LoggedIn,      "LoggedIn property should be true after the user logs in."); 

do this:

mockApiHelper.Verify( x =>     x.Connect(It.IsAny<string>(), It.IsAny<string>(),         It.IsAny<string>()), Times.Once());  

Change times to whatever you expect. If you expect particular values, replace the relevant It.IsAny<string>() calls with those actual values.

like image 35
Andy Avatar answered Sep 21 '22 02:09

Andy