AutoConfiguredMoqCustomization and unsettable properties - moq

How do I force AutoFixture, that has been configured with AutoConfiguredMoqCustomization, to automatically mock interfaces and its read-only properties?
To make things clear, let's assume I have such an interface:
public interface A {
int Property {get;}
}
and such class:
public class SomeClass {
public SomeClass(A dependency) {}
}
What I want is to have dependency resolved to a mock that will return something in dependency.Property:
var fixture = new Fixture().Customize(new AutoConfiguredMoqCustomization());
var sut = fixture.Create<SomeClass>(); // <- dependency passed to SomeClass' constructor will have .Property returning null

This is due to a bug introduced in Moq 4.2.1502.911, where SetupAllProperties overrides previous setups done on get-only properties.
Here's a simpler repro:
public interface Interface
{
string Property { get; }
}
var a = new Mock<Interface>();
a.Setup(x => x.Property).Returns("test");
a.SetupAllProperties();
Assert.NotNull(a.Object.Property);
This is sort of what AutoFixture does behind the scenes to create an instance of Interface. This test fails with versions of Moq equal to or greater than 4.2.1502.911, but passes with lower versions.
Simply run this on the Package Manager Console:
install-package Moq -version 4.2.1409.1722
This bug is being tracked here: https://github.com/Moq/moq4/issues/196

Related

RegisterGenericDecorator ignores condition

Conditions:
Autofac: 4.9.1
.NET Framework: 4.7.2
I have a generic command handler:
public interface ICommand<TResult> : IValidatableObject
{
}
public interface ICommandHandler<TCommand, TResult>
where TCommand : ICommand<TResult>, IValidatableObject
{
TResult Handle(TCommand command);
}
I have a decorator that I want to use for multiple, but not all, implementations of the ICommandHandler (I am going to use a custom attribute to differentiate handlers):
public sealed class LoggingDecorator<TCommand, TResult> : ICommandHandler<TCommand, TResult>
where TCommand : ICommand<TResult>, IValidatableObject
{
private readonly ICommandHandler<TCommand, TResult> _handler;
public LoggingDecorator(ICommandHandler<TCommand, TResult> handler)
{
_handler = handler;
}
public TResult Handle(TCommand command)
{
var test = 0;
return _handler.Handle(command);
}
}
I am trying to register them with AutoFac as follows:
builder.RegisterAssemblyTypes(ThisAssembly)
.AsClosedTypesOf(typeof(ICommandHandler<,>))
.AsImplementedInterfaces();
builder.RegisterGenericDecorator(
decoratorType: typeof(LoggingDecorator<,>),
serviceType: typeof(ICommandHandler<,>),
condition: _decoratorContext =>
{
return false; // true;
});
Seems like the condition is ignored, the decorator is "assigned" to all handlers always.
Have I mis-configured the registration in AutoFac? Or did I miss something else?
How to achieve that the decorator is not registered if the condition returns 'false' in RegisterGenericDecorator method ?
Autofac 4.9.1 is a pretty old version now (3+ yrs). I know that some behaviour around decorator conditions was fixed in v6.0.0; see this issue where upgrading fixed someone's problem that sounds similar to yours.
I'd suggest upgrading to the latest version; if upgrading doesn't fix it, put together a minimal repro and raise an issue on our github repo.

Creating proxies for real objects

I want to write an integration test using a real repository but also verify behavior of the repository
SomeService(IRepository r) calls r.QuerySomething()
And I've been trying to achieve this using Moq:
var mock = new Mock<IRepository >(() => new Repository());
mock.CallBase = true;
The trouble is that it never calls methods from Repository nor does it call it's constructor. The lambda over there is meant for getting ctor parameters (if type is a class) not for object initialization.
Q: How do I wrap new Repository() into a Mock<IIRepository> so I can verify calls?
NB: it works if the type give is a class but I cannot then use it for verifying since they implementatin is not virtual.
Alternatively is there some other nuget that can help me achieve this?
There is a technique that I use for testing brownfiled legacy code, it can probably help, in what you're trying to achieve. You can introduce a decorator into your tests project that wraps your original implementation, but also implements the IRepository interface.
class TestRepository : IRepostiory
{
public TestRepository(Repository next)
{
this.next = next;
}
}
Inside this class you can declare all the interface members as virtual.
class TestRepository : IRepostiory
{
public virtual IReadOnlyList<Client> GetByName(string name)
{
return this.next.GetByName(name);
}
}
Now you can use the TestRepository in place of your original implementation and also create a mock that verifies the calls to this class.
var repository = new Repository();
var sutMock = new Mock<TestRepository>(repository) { CallBase = true };
var sut = sutMock.Object;
sut.GetByName("John Doe");
sutMock.Verify(x => x.GetByName("John Doe"), Times.Once);
NB: The fact that you'd need a legacy code testing technique probably indicates to a code smell. I would recommend, as a first step, splitting the tests that assert the mock from those that assert the real implementation results (changes in the persistence layer).

Instantiate DbContext-derived class with Mehdime.Entity AmbientDbContextLocator

can anyone tell me what I am doing wrong?
I am wanting to use Mehdime.Entity from https://www.nuget.org/packages/Mehdime.Entity in order to manage my DBContext-derived classes in a Console Application. I am also using NInject.
The connection strings for my DBContext-derived classes are partially generated from standard app.config ConnectionStrings and also by an AppDomain value that (in my Console App case) comes in via a command line argument.
My DBContext-derived classes have their connection strings prepared using a program-implemented class which takes into account of the command line argument as follows:
public class TaskManagementDbContext : DbContext
{
public TaskManagementDbContext(IConnectionStringResolver csr) :
base(csr.GetConnectionString("Default"))
{
}
}
(IConnectionStringResolver basically implements GetConnectionString() which returns the connection string by using given named standard app.config ConnectionString and the command line argument.
This is fine when I use NInject to instantiate the DbContext directly but when trying to use with Mehdime.Entity, it is AmbientDbContextLocator that is doing the instantiation and it throws a MissingMethodException because it requires my DBContext-derived class to have a parameterless constructor:
public class TaskRepository : ITaskRepository
{
private readonly IAmbientDbContextLocator _ambientDbContextLocator;
private TaskManagementDbContext DbContext
{
get
{
// MissingMethodException thrown "No parameterless constructor defined for this object"
var dbContext = _ambientDbContextLocator.Get<TaskManagementDbContext>();
...
}
}
How should I provide a connection string to my DBContext-derived classes at run-time in this situation? I suspect I am going about this the wrong way. Thanks.
OK. I've worked out the solution and I'm putting it here for anyone else with this issue:
Create your own implementation of IDbContextFactory (see below). I put this in the same class library as my Data Access Layer (i.e. my DbContexts). You will see in my example how I "look for" a specific constructor prototype (in my case, 1 parameter of type IDbContextFactory - your's will no doubt be different). If found, get the actual parameters and invoke a new instance of your DBContext-derived class. If not found, you can throw an exception or in my case, try to call the default constructor (if exists).
Code:
using System;
using System.Data.Entity;
using Mehdime.Entity;
using Ninject;
using TaskProcessor.Common;
namespace TaskProcessor.Data.Connection
{
public class DbContextWithCSRFactory : IDbContextFactory
{
public TDbContext CreateDbContext<TDbContext>() where TDbContext : DbContext
{
// Try to locate a constuctor with a single IConnectionStringResolver parameter...
var ci = typeof(TDbContext).GetConstructor(new[] { typeof(IConnectionStringResolver) });
if(ci != null)
{
// Call it with the actual parameter
var param1 = GlobalKernel.Instance.Get<IConnectionStringResolver>();
return (TDbContext)ci.Invoke(new object[] { param1 });
}
// Call parameterless constuctor instead (this is the default of what DbContextScope does)
return (TDbContext)Activator.CreateInstance<TDbContext>();
}
}
}
Create a binding in NInject so that your IDbContextFactory implementation is called:
Code:
private void AddBindings(IKernel kernel)
{ ...
kernel.Bind<IDbContextFactory>().To<Data.Connection.DbContextWithCSRFactory>().InSingletonScope();
}
Everything now falls into place.

Verifying indirectly called methods with Moq on a mocked object

My app has a ProviderFactory static class that has static utility methods passing back static instances of things like a logger. The rest of my app then can just grab a/the reference to the logger from anywhere without having to pass in the logger (common design practice).
So, another part of my app, the DbCacheProvider, has methods that make calls to the logger so internally it gets a reference to the logger from the factory and then issues calls to it.
My question is that using Moq, I want to verify methods on the logger are being called by the methods within the DbCacheProvider. I can do this using dependency injection when I pass a mock logger into the DbCacheProvider as a parameter, but I'm not passing the logger in (not do I want to). So, how would I verify the DbCacheProvider is making calls to the logger?
If you don't want to pass the logger in through the constructor you'd need to change your ProviderFactory while running unit tests to return your mocked logger.
Anyway there are a couple of reasons it's often suggested to set up dependency injection:
Your tests are more straightforward and don't involve finagling with custom factories
IoC frameworks like Unity, Ninject and Autofac make it easy to create objects when their dependencies are set up this way. If you set up all of your objects this way, the framework will do all the heavy lifting of creating the right objects and passing them in for you. The dependency injection is done automatically and won't be a burden for you.
Old question without an answer, I had a similar problem and solved it like this:
I have the following sample code and need to verify that not only was a method called but was called with a specific value.
public interface ILog
{
void Info(string message);
}
public interface ILogFactory
{
ILog GetLogger();
}
This is the class being tested, where the interface items are being injected:
public class NewAction
{
readonly ILogFactory _logger;
public NewAction(ILogFactory logger)
{
_logger = logger;
}
public void Step1()
{
_logger.GetLogger().Info("Step 1");
}
public void Step2()
{
_logger.GetLogger().Info("Step 2");
}
}
This is obviously a very simplistic view of my actual code, but I needed to verify that Step1 and Step2 are behaving as expected and passed the correct values to the Log, this would mean I also needed to ensure they occurred in the right order. My test:
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
// Arrange
var log = new Mock<ILog>();
var factory = new Mock<ILogFactory>();
factory.Setup(l => l.GetLogger()).Returns(log.Object);
// Act
var action = new NewAction(factory.Object);
action.Step1();
action.Step2();
// Assert
factory.Verify(l => l.GetLogger());
log.Verify(l => l.Info(It.Is<string>(s => s == "Step 1")));
log.Verify(l => l.Info(It.Is<string>(s => s == "Step 2")));
}
}
Hope this helps.

Using Microsoft Unity IOC, how can you pass it an existing object to inject?

So if I have:
public class CustomerViewModel
{
public CustomerViewModel(ICustomer customer)
{
this.customer = customer
}
}
then is there a way to achieve:
ICustomerViewModel customerViewModel = container.Resolve<ICustomerViewModel>(existingCustomer);
If you want to build-up an existing instance through property and method injection, you can use the following:
var model = new CustomerViewModel(customer);
model = container.BuildUp(model);
In general I would not recommend using this feature of Unity. Sometimes you need it, but it's usually a warning sign that could be fixed by adjusting the design a bit to work more naturally with IoC as a pattern (not a framework). With more details on how you are using it, the SO community can probably offer some other options...
Since the dependency injection container is designed to provide finished objects, you'll need to use a factory pattern (which is quite common in these cases) to achieve your desired configuration:
public interface ICustomerViewModelFactory {
public ICustomerViewModel GetModelFor(ICustomer customer);
}
public class CustomerViewModelFactory : ICustomerViewModelFactory {
public ICustomerViewModel GetModelFor(ICustomer customer) {
return new CustomerViewModel(customer);
}
}
// elsewhere...
container.RegisterInstance<ICustomerViewModelFactory>(new CustomerViewModelFactory());
// and finally...
ICustomerViewModelFactory factory = container.Resolve<ICustomerViewModelFactory>();
ICustomerViewModel customerViewModel = factory.GetModelFor(existingCustomer);
Check the 'Can I pass constructor parameters to Unity's Resolve() method?' question (also on Stack Overflow).

Resources