It.IsAny<T>() used as a mocked object - c#

Using moq, it is usual to provide a mock for an interface type T by using Mock.Of<T>(). But alternatively It.IsAny<T>() returns an Expression that also seems to be usable as an object in place of an object of type T. I've only seen It.IsAny<T>() used to define arguments for method calls in Setup(). What is the difference between Mock.Of<T>() and It.IsAny<T>() (besides syntax obviously)? Are there any circumstances where It.IsAny<T>() should be used to provide a mock over Mock.Of<T>()?
Here is an example of what I'm asking, which I'll build on Ufuk's answer. The mock provided to new UserService() can be either It.IsAny<IUserRepository>() or Mock.Of<IUserRepository>(). In this case, I'm not interested in setting up anything special about these mocks, only that they exist to satisfy the compiler. The Assert.IsTrue() statements are agnostic to the supplied IUserRepository for the purposes of these tests. The question is: are It.IsAny<IUserRepository>() and Mock.Of<IUserRepository>() functionally equivalent in this instance?
[TestFixture]
public class MoqTests
{
[Test]
public void TestInitializationWithItIsAny()
{
var subject = new UserService( It.IsAny<IUserRepository>() ); // It.IsAny<T>
_userService.RegisterUser("abc");
Assert.IsTrue( _userService.IsInitialized() );
}
[Test]
public void TestInitializationWithMockOf()
{
var subject = new UserService( Mock.Of<IUserRepository>() ); // Mock.Of<T>
_userService.RegisterUser("abc");
Assert.IsTrue( _userService.IsInitialized() );
}
}
public class UserService
{
private readonly IUserRepository _userRepository;
private bool _isInitialized = false;
public UserService(IUserRepository userRepository)
{
_userRepository = userRepository;
}
public bool RegisterUser(string userName)
{
_isInitialized = true;
User user = new User { UserName = userName, CreatedOn = DateTime.Now };
return _userRepository.RegisterUser(user);
}
public bool IsInitialized()
{
return _isInitialized;
}
}
public interface IUserRepository
{
bool RegisterUser(User user);
}
public class User
{
public string UserName { get; set; }
public DateTime CreatedOn { get; set; }
}

It.IsAny<T> is used to skip validation in mocked method parameters.
serviceMock.Setup(mock => mock.GetUser(It.IsAny<int>())).Returns(someResult);
You have to pass an integer as a parameter in mock callback to make the test compile. You may not know what value will be sent to mocked component(usually true for reference types) or you may not even care. It.IsAny<T>() provides you to write tests without over specification.
It.IsAny<T>() returns an instance of T, not Mock<T> so it's not a mock.
Take a look at these test cases:
[TestFixture]
public class MoqTests
{
private Mock<IUserRepository> _repository;
private UserService _userService;
[SetUp]
public void Setup()
{
_repository = new Mock<IUserRepository>(MockBehavior.Strict);
_userService = new UserService(_repository.Object);
}
[Test]
public void RegisterUserWithItIsAny()
{
_repository.Setup(item => item.RegisterUser(It.IsAny<User>())).Returns(true);
bool result = _userService.RegisterUser("abc");
Assert.True(result);
}
[Test]
public void RegisterUserWithMockOf()
{
_repository.Setup(item => item.RegisterUser(Mock.Of<User>())).Returns(true);
bool result = _userService.RegisterUser("abc");
Assert.True(result);
}
[TearDown]
public void TearDown()
{
_repository.VerifyAll();
}
}
public class UserService
{
private readonly IUserRepository _userRepository;
public UserService(IUserRepository userRepository)
{
_userRepository = userRepository;
}
public bool RegisterUser(string userName)
{
User user = new User { UserName = userName, CreatedOn = DateTime.Now };
return _userRepository.RegisterUser(user);
}
}
public interface IUserRepository
{
bool RegisterUser(User user);
}
public class User
{
public string UserName { get; set; }
public DateTime CreatedOn { get; set; }
}
Second test fails because Moq does not recognize the mock instance as parameter value. Mock.Of<T>() seems useful when you want to create mocks quickly with a single setup contained in predicate parameter.
Update:
I rewrote the test just as in your examples.
[SetUp]
public void Setup()
{
_userService = new UserService(It.IsAny<IUserRepository>());
}
[Test]
public void RegisterUserWithItIsAny()
{
bool result = _userService.RegisterUser("abc");
Assert.True(result);
}
[Test]
public void RegisterUserWithMockOf()
{
bool result = _userService.RegisterUser("abc");
Assert.True(result);
}
Both tests fail because It.IsAny<T>() returns null. If you have used Mock.Of<T>() it would create a mock with default behavior. That means they are not functionally equivalent in this case too.

Related

GuardClauseAssertion does not fail if limited to only public constructors

Why does this unit test not fail when no guard clause is present?
[Test]
public void ConstructorLooksGuardedAgainstNulls()
{
// ARRANGE
var fixture = new Fixture();
var assertion = fixture.Create<GuardClauseAssertion>();
// ACT & ASSERT
assertion.Verify(typeof(TestClass).GetConstructors(BindingFlags.Public));
}
Classes used in unit test:
public class TestBaseClass
{
private readonly string _firstDependency;
private readonly string _secondDependency;
protected TestBaseClass(string firstDependency, string secondDependency)
{
_firstDependency = firstDependency;
_secondDependency = secondDependency;
}
}
public class TestClass : TestBaseClass
{
public TestClass(string firstDependency)
: base(firstDependency, string.Empty)
{
}
}
I removed all the irrelevant lines.
This will return all public constructors, and then the test will fail as expected:
typeof(TestClass).GetConstructors()
The version with the BindingFlags parameter doesn't return the public constructors (although it reads like it really should do). Because no constructor are found, the test passes
typeof(TestClass).GetConstructors(BindingFlags.Public)

Testing Code with Third Party Object Instantiation

New to unit testing and trying to get my head around some simple tests for a piece of code which gets or creates a template if it doesn't exist (in Umbraco 8).
The method is quite simple, when Initialise is called, it gets the template and if it doesn't exist, creates it:
using Umbraco.Core.Composing;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
namespace Papermoon.Umbraco.Aldus.Core.Components
{
public class TemplateComponent : IComponent
{
private readonly IFileService _fileService;
public TemplateComponent(IFileService fileService)
{
_fileService = fileService;
}
public void Initialize()
{
ITemplate blogTemplate = _fileService.GetTemplate("aldusBlog");
if (blogTemplate == null)
{
blogTemplate = new Template("Aldus Blog", "aldusBlog");
_fileService.SaveTemplate(blogTemplate);
}
}
public void Terminate() { }
}
}
Works okay, no problem.
I'm trying to write a few tests, the first checks if _fileService.GetTemplate is called.
The second test should check that _fileService.SaveTemplate() is called if that returns null.
using Moq;
using NUnit.Framework;
using Papermoon.Umbraco.Aldus.Core.Components;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
namespace Papermoon.Umbraco.Aldus.Core.Tests.Components
{
[TestFixture]
public class TemplateComponentTests
{
private Mock<IFileService> _fileService;
private TemplateComponent _component;
[SetUp]
public void SetUp()
{
_fileService = new Mock<IFileService>();
_component = new TemplateComponent(_fileService.Object);
}
[Test]
public void Initialise_WhenCalled_GetsBlogTemplate()
{
_component.Initialize();
_fileService.Verify(s => s.GetTemplate("aldusBlog"), Times.Once);
}
[Test]
public void Initialise_BlogTemplateDoesNotExist_CreateTemplate()
{
_fileService
.Setup(s => s.GetTemplate("aldusBlog"))
.Returns((ITemplate) null);
_component.Initialize();
_fileService.Verify(s => s.SaveTemplate(It.Is<ITemplate>(p => p.Alias == "aldusBlog"), -1), Times.Once());
}
}
}
The trouble when I do this is that the blogTemplate = new Template("Aldus Blog", "aldusBlog"); throws an error:
Can not get Current.Config during composition. Use composition.Config.
I assume this is because I don't have any kind of context which leads me to think that the ITemplate needs to be mocked. However, because new Template("Aldus Blog", "aldusBlog"); will always be called, it will always throw this error.
Obviously the code isn't bullet proof, so how do I refactor this to be testable?
That 3rd party class is probably tightly coupled to an implementation concern that does not exist or is not configured when unit testing in isolation.
abstract that object creation out into a factory.
public interface ITemplateFactory {
ITemplate Create(string name, string alias);
}
whose implementation can be injected at run-time
public class DefaultTemplateFactory : ITemplateFactory {
public ITemplate Create(string name, string alias) {
return new Template(name, alias);
}
}
Provided it is registered at the composition root during startup
This now allow the component to be loosely coupled away from implementation concerns
public class TemplateComponent : IComponent {
private readonly IFileService fileService;
private readonly ITemplateFactory templateFactory;
public TemplateComponent(IFileService fileService, ITemplateFactory templateFactory) {
this.fileService = fileService;
this.templateFactory = templateFactory;
}
public void Initialize() {
ITemplate blogTemplate = fileService.GetTemplate("aldusBlog");
if (blogTemplate == null) {
blogTemplate = templateFactory.Create("Aldus Blog", "aldusBlog");
fileService.SaveTemplate(blogTemplate);
}
}
public void Terminate() { }
}
That can be replaced as needed when testing in isolation
[TestFixture]
public class TemplateComponentTests {
private Mock<IFileService> fileService;
private Mock<ITemplateFactory> templateFactory;
private TemplateComponent component;
string templateAlias = "aldusBlog";
[SetUp]
public void SetUp() {
//Arrange
fileService = new Mock<IFileService>();
templateFactory = new Mock<ITemplateFactory>();
templateFactory.Setup(_ => _.Create(It.IsAny<string>(), It.IsAny<string>()))
.Returns((string name, string alias) =>
Mock.Of<ITemplate>(_ => _.Alias == alias && _.Name == name)
);
component = new TemplateComponent(fileService.Object, templateFactory.Object);
}
[Test]
public void Initialise_WhenCalled_GetsBlogTemplate() {
//Act
component.Initialize();
//Assert
fileService.Verify(s => s.GetTemplate(templateAlias), Times.Once);
}
[Test]
public void Initialise_BlogTemplateDoesNotExist_CreateTemplate() {
//Act
component.Initialize();
//Assert
fileService.Verify(s => s.SaveTemplate(It.Is<ITemplate>(p => p.Alias == templateAlias), 0), Times.Once());
}
}

Moq an object in a static class

I can't get Moq to mock an object that gets created in a static method.
Here is my moq and code
code:
public interface IConfigHelper
{
string GetConfiguration(string sectionName, string elementName);
}
public class ConfigHelper : IConfigHelper
{
public ConfigHelper() { }
public virtual string GetConfiguration(string sectionName, string elementName)
{
string retValue = String.Empty;
//Does things to get configuration and return a value
return retValue;
}
}
public class myRealClass
{
public myRealClass(){}
public string myworkingMethod()
{
var retValue = String.Empty;
retValue = utilSvc.GetConfigurationValue();
return retValue;
}
}
public static class utilSvc
{
public static string GetConfigurationValue()
{
ConfigHelper configUtil = new ConfigHelper(); //NOT BEING MOCKED
return configUtil.GetConfiguration("sectionName/sectionElement", "ClinicalSystem");
}
}
the Test using Moq
[TestFixture(TestName = "Tests")]
public class Tests
{
private Mock<IConfigHelper> configHelperMOCK;
[SetUp]
public void Setup()
{
configHelperMOCK = new Mock<IConfigHelper>();
}
[Test]
public void serviceIsBPManagementForValidSource()
{
//Arrange
string sectionName = "sectionName/sectionElement";
string clinicalElementName = "ClinicalSystem";
string clinicalElementValue = "Zedmed";
configHelperMOCK.Setup(s => s.GetConfiguration(sectionName, clinicalElementName)).Returns(clinicalElementValue);
//act
// the call to myRealClass
//assert
// test assertions
}
}
The issue that I am having is with this line:
ConfigHelper configUtil = new ConfigHelper(); //NOT BEING MOCKED
I cannot get the moq to Mock the object.
I do not want the code to read the config file. I wish to moq away this instance of ConfigHelper
You can't wrap the static class/method but you can redirect it
public static class UtilSvc
{
static UtilSvc()
{
CreatorFunc = () => new ConfigHelper();
}
public static Func<IConfigHelper> CreatorFunc { get; set; }
public static string GetConfigurationValue()
{
var configUtil = CreatorFunc();
return configUtil.GetConfiguration("sectionName/sectionElement",
"ClinicalSystem");
}
}
and then in the test
//...
private Mock<IConfigHelper> configHelperMOCK;
[SetUp]
public void Setup()
{
configHelperMOCK = new Mock<IConfigHelper>();
UtilService.CreatorFunc = () => configHelperMOCK.Object;
}
//...
You cannot mock static class. I would rather propose to inject that IConfigHelper into the myRealClass. That is the usual way how to decouple dependencies and use DI.
public class myRealClass
{
private IConfigHelper _configHelper;
public myRealClass(IConfigHelper configHelper)
{
_configHelper = configHelper;
}
public string myworkingMethod()
{
var retValue = String.Empty;
retValue = _configHelper.GetConfigurationValue();
return retValue;
}
}
Avoid coupling your code to static classes, which in most cases cause you code be to difficult to maintain and test.
Follow the Explicit Dependencies Principle
Methods and classes should explicitly require (typically through
method parameters or constructor parameters) any collaborating objects
they need in order to function correctly.
Give the article a read. It is short and very informative.
If you want to keep the static class then you wrap the static class behind an abstraction.
public interface IUtilSvc {
string GetConfigurationValue();
}
public class utilSvcWrapper : IUtilSvc {
public string GetConfigurationValue() {
return utilSvc.GetConfigurationValue(); //Calling static service
}
}
Or another option is that utlSvc does not have to be static if can be injected into dependent classes
public class utilSvc : IUtilScv {
private readonly IConfigHelper configUtil;
public utilSvc(IConfigHelper configHelper) {
configUtil = configHelper;
}
public string GetConfigurationValue() {
return configUtil.GetConfiguration("sectionName/sectionElement", "ClinicalSystem");
}
}
Inject the IUtilScv into the dependent class so that it is no longer dependent on static class.
public class myRealClass {
private readonly IUtilScv utilSvc;
//Explicit dependency inject via constructor
public myRealClass(IUtilScv utilSvc) {
this.utilSvc = utilSvc;
}
public string myworkingMethod() {
var retValue = utilSvc.GetConfiguration();
return retValue;
}
}
In that case you don't even need IConfigHelper when testing as it has also been abstracted away. And you only need to mock the dependencies needed for the test.
[TestFixture(TestName = "Tests")]
public class Tests {
private Mock<IUtilScv> utilScvMOCK;
[SetUp]
public void Setup() {
utilScvMOCK = new Mock<IUtilScv>();
}
[Test]
public void serviceIsBPManagementForValidSource() {
//Arrange
var expectedClinicalElementValue = "Zedmed";
utilScvMOCK
.Setup(s => s.GetConfiguration())
.Returns(expectedClinicalElementValue)
.Verifiable();
var sut = new myRealClass(utilScvMOCK.Object);
//Act
var actualClinicalElementValue = sut.myworkingMethod();
//Assert
configHelperMOCK.Verify();
Assert.AreEqual(expectedClinicalElementValue, actualClinicalElementValue);
}
}

NUnit test and how to initialize DependencyManager.Resolve

I have the following code that I need to initiate within my integration test in my C# NUnit test.
How can I initialize the DependencyManager.Resolve method please?
Many thanks,
Unit test calls this method
public static Account GetCustomer(string databaseName)
{
Database db = DatabaseFactory.CreateDatabase(databaseName);
using(DbCommand cmd = db...)
{
}
}
CreateDatabase method
public static Database CreateDatabase(string name)
{
IDbFactory factory = DependencyManager.Resolve<IDbFactory>();
return factory.GetDatabase(name);
}
Unit test
[Test]
public void When_I_Call_GetCustomer_A_Customer_Is_Returned()
{
var result = CustomerAccount.GetCustomer(..);
}
Update
DependencyManager implementation shown below
public class DependencyManager
{
public static T Resolve<T>(string key = "", ParamDictionary parameters = null)
{
return Resolver.Resolve<T>(key, parameters);
}
}
private static volatile IDependencyResolver resolver;
...
public static IDependencyResolver Resolver
{
get { return DependencyManager.resolver; }
}
It eventually gets to
public class CastleDependencyContainer : IDependencyBuilder, IDependencyResolver

Limiting Scope of UnitTest using Rhino stubs

I'm working on a unit test for a service method, that has dependencies. Simplified:
public class ConditionChecker
{
private SqlConnection _connection;
public bool CanDoSomething()
{
return _connection.State == ConnectionState.Open;
}
}
public class A
{
public ConditionChecker Checker { get; set; }
public bool CanInvokeA()
{
return Checker.CanDoSomething();
}
}
[TestClass]
public class ATests
{
[TestMethod]
public void TestCanInvokeA()
{
// arrange
A a = new A();
ConditionChecker checker = MockRepository.GenerateStub<ConditionChecker>();
checker.Stub(x => x.CanDoSomething()).Return(true);
a.Checker = checker;
// act
bool actual = a.CanInvokeA();
// assert
Assert.AreEqual(true, actual);
}
}
What I want is to completely bypass the implementation of ConditionChecker.CanDoSomething, which is why I stub the call, still I run into a null reference Exception during my test, since the _connection member is not set. What am I doing wrong here?
You just mark your method as virtual, it will work:
public virtual bool CanDoSomething()
{
}
Since behind the scene Rhino Mock will create a dynamic proxy for ConditionChecker, so you need to mark virtual to allow Rhino Mock to override it.

Categories

Resources