Using Moq with Windsor -- Object of Type Moq.Mock[IFoo] cannot be converted to IFoo - nunit

I'm trying to set up some Moq repositories to test my service with Castle Windsor as my IOC. Mu service depends on IFoo, so I'm creating a moq instance that implements IFoo and injecting it into the container like so:
_container.AddComponent("AutoBill",
typeof (AutoBillService), typeof (AutoBillService));
var mockUserRepository = new Mock<IUserRepository>();
var testUser = new User()
{
FirstName = "TestFirst",
LastName = "TestLast",
UID=1
};
mockUserRepository.Setup(repo => repo.GetUser(testUser.UID))
.Returns(testUser);
_container.Kernel.AddComponentInstance("UserRepository",
typeof(IUserRepository), mockUserRepository);
var service = _container.Resolve<AutoBillService>(); //FAIL
Doing this gives me an exception:
System.ArgumentException: Object of type 'Moq.Mock`1[IUserRepository]' cannot be converted to type 'IUserRepository'
Can anyone see what I'm doing wrong?

You should pass mockUserRepository.Object instead of mockUserRepository.
This would be a lot more evident if you used the strongly typed API:
_container.Register(Component
.For<IUserRepository>()
.Instance(mockUserRepository.Object));
This compiles because the Object property implements IUserRepository.

I head the same problem with Castle Windsor.
A dinamyc initialization with method:
container.Register(Component.For<IUserRepository>()
.Instance(mockUserRepository.Object));
didn't work until I removed from my caslteRepository.config file pre-initialized repositories (like your IUserRepository) and left container "empty" from repositories.

Related

Template10 MVVM IoC Inject ViewModel into Shell View

I'm looking for the best way to inject a ViewModel into a Shell view.
I'm using Autofac (but I can adopt code from other IoC containers if sample is available). I have got the other VMs injecting correctly - but the method that resolves the VM using ResoleForPage method of the App class.
I'm fairly new to UWP developement and any help is greatly appreciated!
Passing a ViewModel to the Shell is indeed simpler than passing it to the other pages, because the Shell is the only page that is created explicitly by us: so, it should be enough to add a parameter to the constructor of the Shell of type ShellViewModel:
public Shell()
{
Instance = this;
this.InitializeComponent();
}
public Shell(INavigationService navService, ShellViewModel model) : this()
{
navigationMenu.NavigationService = navService;
navigationMenu.RefreshStyles(App.Current.RequestedTheme, true);
this.DataContext = model;
}
then expose the DataContext in a strongly typed way, as with any other pages (useful mainly if you use x:Bind bindings in xaml):
public ShellViewModel ViewModel => DataContext as ShellViewModel;
And now you just have to pass an instance of your ViewModel class, pulling it from your IoC container, when you create the Shell. In the latest Template 10 template for VS2017, it should be in the CreateRootElement method of the App class:
public override UIElement CreateRootElement(IActivatedEventArgs e)
{
var service = NavigationServiceFactory(BackButton.Attach, ExistingContent.Include);
return new Template10.Controls.ModalDialog
{
DisableBackButtonWhenModal = true,
Content = new Shell(service, new ShellViewModel()),
};
}
of course replacing new ShellViewModel() with the code to pull it from Autofac.

Can not instantiate proxy...Could not find a parameterless constructor

I am trying to create a unit test using Moq which tests the MongoDB.AspNet.Identity V2 provider. This line is giving me grief:
var appUser = new Mock<PreRegistrationMVC.Models.ApplicationUser>();
var userStore = new Mock<MongoDB.AspNet.Identity.UserStore<PreRegistrationMVC.Models.ApplicationUser>>();
It seems the userStore won't instantiate properly here is the error.
Castle.DynamicProxy.InvalidProxyConstructorArgumentsException was unhandled by user code
HResult=-2147024809
Message=Can not instantiate proxy of class: MongoDB.AspNet.Identity.UserStore`1[[MVC.Models.ApplicationUser, MVC, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].
Could not find a parameterless constructor.
Source=Moq
StackTrace:
at Castle.DynamicProxy.ProxyGenerator.CreateClassProxyInstance(Type proxyType, List`1 proxyArguments, Type classToProxy, Object[] constructorArguments)
at Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, Object[] constructorArguments, IInterceptor[] interceptors)
at Moq.Proxy.CastleProxyFactory.CreateProxy(Type mockType, ICallInterceptor interceptor, Type[] interfaces, Object[] arguments)
at Moq.Mock`1.<InitializeInstance>b__2()
at Moq.PexProtector.Invoke(Action action)
at Moq.Mock`1.InitializeInstance()
at Moq.Mock`1.OnGetObject()
at Moq.Mock.GetObject()
at Moq.Mock.get_Object()
at Moq.Mock`1.get_Object()
at MVC_Tests.Identity.Accounts.AccountController_Test.TestSuccessfulRegister() in c:\Users\Tim\Documents\Visual Studio 2013\Projects\PreRegistrationApp\MVC_Tests\Identity\Accounts\AccountController_Test.cs:line 108
InnerException:
I am completely new to Moq so I am looking for:
What type of settings are needed for Moq to instantiate this? Is there something about the UserStore class that won't play well with Moq?
Thanks for reading.
MOQ is good for mocking interfaces, but does not work so well with concrete classes. So instead of mocking concrete class, ask for the inteface:
var userStore = new Mock<IUserStore<PreRegistrationMVC.Models.ApplicationUser>>();
Also ApplicationUser should be POCO, so no need to mock it, just create its instance without MOQ and use in tests.
You can try referring Mock behavior,as shown below
Mock<testClass>(MockBehavior.Strict, new object[] {"Hello"});
I had this problem. I had written...
var x = new Mock<Concrete>();
... instead of ...
var x = new Mock<IConcrete>();
I know this is a late response, but I was looking for an answer and couldn't find exactly what I needed, but when creating a mock, you can pass the parameters to your wanted constructor.
So for example if you have class like this:
public class Foo
{
private readonly Boo _boo;
public Foo(Boo boo)
{
_boo = boo;
}
}
You can mock it like this:
private readonly Mock<Foo> _foo = new Mock<Foo>(new Mock<Boo>().Object);
Add an empty constructor to your ApplicationUser class.

MVC5 EF6 with migrations - seeding a membership user

I am setting up my seed methods in my migration's configuration class.
I have added a reference to the following name spaces
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
and wrote up the following method that gets called from the Seed method
private void SeedMembership(MyDbContext context)
{
var user = new ApplicationUser() { UserName = "demo"};
UserManager<ApplicationUser> userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
var result = UserManager.Create(user,"demo");
}
The idea was to have this aoto create a user with username=demo and password=demo
but I cant compile getting the following error:
using the generic type 'Microsoft.AspNet.Identity.UserManager<TUser>' requires 1 type argument
I am a bit stuck as to why.
Thanks!
You seem to have a typo:
var result = UserManager.Create(user,"demo");
You should use userManager, note the lower-case u.

Autofac ServiceLocator issue in release v2.4.5.724

I have just upgraded to MVC 3 and likewise need to upgrade Autofac.
The following code was working, but now fails with this error -
This resolve operation has already
ended. When registering components
using lambdas, the IComponentContext
'c' parameter to the lambda cannot be
stored. Instead, either resolve
IComponentContext again from 'c', or
resolve a Func<> based factory to
create subsequent components from.
public static IServiceLocator Locator;
public class ServiceA : IServiceA
{
}
public interface IServiceA
{
}
[Test]
public void TestAutofacServiceLocator()
{
// This resolve operation has already ended. When registering components using lambdas, the IComponentContext 'c' parameter to the lambda cannot be stored.
// Instead, either resolve IComponentContext again from 'c', or resolve a Func<> based factory to create subsequent components from.
var builder = new ContainerBuilder();
builder.RegisterType<ServiceA>().As<IServiceA>();
builder.Register(c => Locator = new AutofacServiceLocator(c)).As<IServiceLocator>().SingleInstance();
var container = builder.Build();
container.Resolve<IServiceLocator>();
var x = Locator.GetInstance<IServiceA>();
Assert.NotNull(x);
}
How should I resgister IServiceLocator?
I looked at the answer to question autofac registration issue in release v2.4.5.724 but I'm still confused.
I really should have read Nick's error message, the answer was in the message.
Fixed !!
builder.Register(c => Locator = new AutofacServiceLocator(c.Resolve()))
.As().SingleInstance();

autofac registration issue in release v2.4.5.724

I have the following registration
builder.Register<Func<Type, IRequestHandler>>(
c => request => (IRequestHandler)c.Resolve(request));
Basically I am trying to register a factory method that resolves an instance of IRequestHandler from a given type.
This works fine until the version 2.4.3.700. But now I am getting a the following error..
Cannot access a disposed object.
Object name: 'This resolve operation has already ended. When
registering components using lambdas,
the IComponentContext 'c' parameter to
the lambda cannot be stored. Instead,
either resolve IComponentContext again
from 'c', or resolve a Func<> based
factory to create subsequent
components from.'.
UPDATE
I was trying to limit autofac's exposure to the rest of the projects in the solution. Nick, thanks for the hint, now my registration looks like this...
builder.Register<Func<Type,IRequestHandler>>(c =>
{
var handlers = c.Resolve<IIndex<Type,RequestHandler>>();
return request => handlers[request];
});
The c in this expression is a temporary, so this code while previously functional, is broken. Autofac 2.4.5 detects this problem while earlier versions silently ignored it.
To fix the issue, explicitly resolve IComponentContext:
builder.Register<Func<Type, IRequestHandler>>(c => {
var ctx = c.Resolve<IComponentContext>();
return request => (IRequestHandler)ctx.Resolve(request));
});
The functionality you're emulating here might be better represented using keys and indexes, e.g. see Interrupted chain of IoC or http://code.google.com/p/autofac/wiki/TypedNamedAndKeyedServices.
I had a similar problem as the user6130. I wanted to avoid using IIndex in my class implementation and pass in a service resolver into my constructor instead.
So now I have my service implementation with the following constructor:
public MvcMailer(Converter<string, MailerBase> mailerResolver)
{
_resolver = mailerResolver;
}
I wanted to used keyed services without directly relying on the Autofac namespace. I was getting the same error until I restructured the configuration as such.
1) Scan for all my mailer implementations and index via class name (could be improved)
builder.RegisterAssemblyTypes(System.Reflection.Assembly.GetExecutingAssembly())
.Where(t => t.Name.EndsWith("Mailer")).Keyed<Mvc.Mailer.MailerBase>(t => t.Name.Replace("Mailer", "").ToLower());
2) Register the converter in Autofac config
builder.Register<System.Converter<string,Mvc.Mailer.MailerBase>>(c => {
var all = c.Resolve<Autofac.Features.Indexed.IIndex<string,Mvc.Mailer.MailerBase>>();
return delegate(string key)
{
return all[key];
};
});
3) Register like other types of components and let Autofac handle the Converter injection
builder.RegisterType<Mailers.MvcMailer>().As<Mailers.IMailer>();