testing controller using MOQ calling repository - asp.net-mvc-2

I'm very new to Mocking. In the below example i'm using Moq and trying to create a _companyRepository. However the second test has a null ref. ie Company is not instantiated.
Assert.AreEqual(viewModel.Company.Name, "MyCompany");
Think i'm missing something silly here.
[TestClass]
public class ErrorControllerTest
{
private Mock<ICompanyRepository> _companyRepository;
public ErrorController CreateErrorController()
{
_companyRepository = new Mock<ICompanyRepository>();
_companyRepository.Setup(c => c.Get(2)).Returns(new Company {Name = "MyCompany"});
return new ErrorController(_companyRepository.Object);
}
[TestMethod]
public void Test()
{
var controller = CreateErrorController();
controller.Test(""); // action is called
var viewModel = (ErrorViewModel)controller.ViewData.Model;
Assert.IsInstanceOfType(controller.ViewData.Model, typeof(ErrorViewModel));
Assert.AreEqual(viewModel.Company.Name, "MyCompany");
}
}
controller
public class ErrorController : Controller
{
private readonly ICompanyRepository _companyRepository;
public ErrorController(ICompanyRepository companyRepository)
{
_companyRepository = companyRepository;
}
public ActionResult Test()
{
var company = _companyRepository.Get(2);
var viewModel = new ErrorViewModel
{
Company = company
};
return View(viewModel);
}
}

this works.... Guess i didn't compile everything. Very dumb.
Tho am i doing this the right way. Appreciate any comments.

Related

Autofac: cannot resolve dependency using factory after ContainerBuilder.Update()

My problem is that I want to use Func<> factory to resolve dependency. And in if I use ContainerBuilder Update() (I need it for mocking some services in integration tests), this factories still resolve outdated instances.
I created simple scenario to reproduce the problem:
class Program
{
static void Main(string[] args)
{
var containerBuilder = new ContainerBuilder();
containerBuilder.RegisterType<Test>().As<ITest>();
containerBuilder.RegisterType<Test1Factory>().As<ITestFactory>();
containerBuilder.RegisterType<TestConsumer>().AsSelf();
var container = containerBuilder.Build();
var tc1 = container.Resolve<TestConsumer>();
var cbupdater = new ContainerBuilder();
cbupdater.RegisterType<Test2>().As<ITest>();
cbupdater.RegisterType<Test2Factory>().As<ITestFactory>();
cbupdater.Update(container);
var tc2 = container.Resolve<TestConsumer>();
Console.ReadLine();
}
}
public interface ITest
{
int Id { get; set; }
}
public class Test : ITest
{
public Test()
{
Id = 1;
}
public int Id { get; set; }
}
public class Test2 : ITest
{
public Test2()
{
Id = 2;
}
public int Id { get; set; }
}
public interface ITestFactory
{
ITest Create();
}
public class Test1Factory : ITestFactory
{
public ITest Create()
{
return new Test();
}
}
public class Test2Factory : ITestFactory
{
public ITest Create()
{
return new Test2();
}
}
public class TestConsumer
{
public TestConsumer(Func<ITest> testFactory, ITest test, ITestFactory customFactory)
{
Console.WriteLine("factory: " + testFactory().Id);
Console.WriteLine("direct: " + test.Id);
Console.WriteLine("MyCustomFactory: " + customFactory.Create().Id);
Console.WriteLine("*************");
Console.WriteLine();
}
}
The output is:
factory: 1 direct: 1 MyCustomFactory: 1
factory: 1 direct: 2 MyCustomFactory: 2
Notice "factory: 1" in both cases.
Am I missing something or I have to create my cusom factory in this scenario?
P.S.
Autofac 3.5.2 or 4.0 beta 8-157
.net 4.5.1
That's by design unfortunately, the reasons, I don't know. Looking at the Autofac code gives you a better insight on how they register items with the same interface definition, in short, all registrations are maintained but the last registration wins (ref). Wait...that's not all, weirdly, for Fun<...>, you actually get them in order. You can easily test by changing the constructor of the TestConsumer class to:
public TestConsumer(Func<ITest> testFactory, IEnumerable<Func<ITest>> testFactories, IEnumerable<ITest> tests, ITest test, ITestFactory customFactory)
{
// ...
}
Note that you get all the Funcs and the ITest registration. You are simply lucky that resolving ITest directly resolves to Test2.
Now, having said all of the above, there is a way described here. You have to create a container without the registration you want to override, therefore:
/// <summary>
/// This has not been tested with all your requirements
/// </summary>
private static IContainer RemoveOldComponents(IContainer container)
{
var builder = new ContainerBuilder();
var components = container.ComponentRegistry.Registrations
.Where(cr => cr.Activator.LimitType != typeof(LifetimeScope))
.Where(cr => cr.Activator.LimitType != typeof(Func<ITest>));
foreach (var c in components)
{
builder.RegisterComponent(c);
}
foreach (var source in container.ComponentRegistry.Sources)
{
builder.RegisterSource(source);
}
return builder.Build();
}
And you can simply change your main method to the following:
static void Main(string[] args)
{
var containerBuilder = new ContainerBuilder();
containerBuilder.RegisterType<Test>().As<ITest>();
containerBuilder.RegisterType<Test1Factory>().As<ITestFactory>();
containerBuilder.RegisterType<TestConsumer>().AsSelf();
var container = containerBuilder.Build();
var tc1 = container.Resolve<TestConsumer>();
container = RemoveOldComponents(container);
var cbupdater = new ContainerBuilder();
cbupdater.RegisterType<Test2>().As<ITest>();
cbupdater.RegisterType<Test2Factory>().As<ITestFactory>();
cbupdater.Update(container);
var tc2 = container.Resolve<TestConsumer>();
Console.ReadLine();
}
PS: Wouldn't it be great to have a method which does the exact opposite of PreserveExistingDefaults()

How can I achieve the following using IOC?

I want to use IOC with my service and I want to instead inject a class not an interface in the constructor as below in the services layer but I do not want to create a new object from the calling layer like var service = new InvoiceService(new ChangeInvoiceDueDateCommand()) instead I want to create something like this from my controller in MVC where the IInvoiceService is injected into the controller constructor but the problem I see is that
public InvoiceController(IInvoiceService invoiceService, IMapper mapper)
{
_invoiceService = invoiceService;
_mapper = mapper;
}
and then called like this
public ActionResult ChangeInvoiceDueDate(InvoiceChangeDueDateViewModel invoiceChangeDueDateViewModel )
{
var request = _mapper.Map<InvoiceChangeDueDateViewModel, ChangeInvoiceDuedateRequest>(invoiceChangeDueDateViewModel);
InvoiceChangeDueDateResponse response = _invoiceService.ChangeDueDate(request);
return View();
}
Service Layer
public class InvoiceService : IInvoiceService
{
private readonly ChangeInvoiceDueDateCommand _changeInvoiceDueDateCommand;
public InvoiceService(ChangeInvoiceDueDateCommand changeInvoiceDueDateCommand)
{
_changeInvoiceDueDateCommand = changeInvoiceDueDateCommand;
}
public InvoiceChangeDueDateResponse ChangeDueDate(ChangeInvoiceDuedateRequest invoiceChangeDueDateRequest)
{
_changeInvoiceDueDateCommand.Execute(invoiceChangeDueDateRequest);
return new InvoiceChangeDueDateResponse {Status = new Status()};
}
}
Command
public class ChangeInvoiceDueDateCommand : ICommand<ChangeInvoiceDuedateRequest>
{
private readonly IRepository<Invoice> _invoiceRepository;
readonly InvoiceDueDateChangeValidator _validator;
public ChangeInvoiceDueDateCommand(IRepository<Invoice> invoiceRepository)
{
_invoiceRepository = invoiceRepository;
_validator = new InvoiceDueDateChangeValidator();
}
public void Execute(ChangeInvoiceDuedateRequest request)
{
if (_validator.IsDuedateValid(request.NewDuedate))
{
Invoice invoice = _invoiceRepository.GetById(request.Id);
invoice.ChangedDueDate(request.NewDuedate);
_invoiceRepository.SaveOrUpdate(invoice);
}
else
{
throw new InvalidDueDateException();
}
}
}
ICommand
public interface ICommand<T> where T : IRequest
{
void Execute(T request);
}
IRequest
public interface IRequest
{
int Id { get; set; }
}
I worked it out. It was just a Windsor syntax issue. It ended up being as simple as registering the Command using the container.Register(Component.For<ChangeInvoiceDueDateCommand>());

Autofac LifetimeScope with BeginLifetimeScope not working

I am trying to evaluate the scoping of Autofac and as I understand it, when an instance has been declared as InstancePerLifetimeScope, then within the using(container.BeginLifetimeScope()) block, we should get the same instance. But in another such block, we should get a different instance. But my code (in linqpad) gives me the same instance. Windsor's lifestylescope however works as I think it should.
Code:
static IContainer glkernel;
void Main()
{
var builder = new ContainerBuilder();
builder.RegisterType<Controller>();
builder.RegisterType<A>().As<IInterface>().InstancePerLifetimeScope();
glkernel = builder.Build();
using (glkernel.BeginLifetimeScope()){
Controller c1 = glkernel.Resolve<Controller>();
c1.GetA();//should get instance 1
c1.GetA();//should get instance 1
}
using (glkernel.BeginLifetimeScope()){
Controller d = glkernel.Resolve<Controller>();
d.GetA();//should get instance 2
d.GetA();//should get instance 2
}
}
public interface IInterface
{
void DoWork(string s);
}
public class A : IInterface
{
public A()
{
ID = "AAA-"+Guid.NewGuid().ToString().Substring(1,4);
}
public string ID { get; set; }
public string Name { get; set; }
public void DoWork(string s)
{
Display(ID,"working...."+s);
}
}
public static void Display(string id, string mesg)
{
mesg.Dump(id);
}
public class Controller
{
public Controller()
{
("controller ins").Dump();
}
public void GetA()
{
//IInterface a = _kernel.Resolve<IInterface>();
foreach(IInterface a in glkernel.Resolve<IEnumerable<IInterface>>())
{
a.DoWork("from A");
}
}
}
The output is:
controller ins
AAA-04a0
working....from A
AAA-04a0
working....from A
controller ins
AAA-04a0
working....from A
AAA-04a0
working....from A
Perhaps my understanding of scoping is wrong. If so, can you please explain.
What do I have to do to get a different instance in the second block?
The problem is you're resolving things out of the container - the glkernel instead of out of the lifetime scope. A container is a lifetime scope - the root lifetime scope.
Resolve out of the lifetime scope instead. That may mean you need to change up your controller to pass in the list of components rather than using service location.
public class Controller
{
private IEnumerable<IInterface> _interfaces;
public Controller(IEnumerable<IInterface> interfaces)
{
this._interfaces = interfaces;
("controller ins").Dump();
}
public void GetA()
{
foreach(IInterface a in this._interfaces)
{
a.DoWork("from A");
}
}
}
Then it's easy enough to switch your resolution code.
using (var scope1 = glkernel.BeginLifetimeScope()){
Controller c1 = scope1.Resolve<Controller>();
c1.GetA();
c1.GetA();
}
using (var scope2 = glkernel.BeginLifetimeScope()){
Controller c2 = scope2.Resolve<Controller>();
c2.GetA();
c2.GetA();
}
The Autofac wiki has some good information on lifetime scopes you might want to check out.

Autofac WithMetadata not working

This is what I've got:
public interface INamed
{
string Name { get; }
}
public interface IService
{
}
public class Service : IService
{
}
public class ServiceUser
{
public ServiceUser(IEnumerable<Lazy<IService, INamed>> services)
{
var cnt = services.Count(); // Always 0.
}
}
var builder = new ContainerBuilder();
builder.Register(c => new Service())
.As<IService>()
.WithMetadata<INamed>(m => m.For(n => n.Name, "Test"));
builder.RegisterType<ServiceUser>();
var container = builder.Build();
var su = container.Resolve<ServiceUser>();
The collection of Lazy<IService, INamed> services in the ServiceUser ctor is always empty. Can you explain what I'm doing wrong? One thing I immediately don't understand is where the concrete implementation of INamed is coming from. I guess Autofac generates that internally? Please help clear things up for me.
Upgrade to the latest Autofac.

how to reference controller function from another controller

Trying to learn ASP MVC coming from Linux/LAMP background (in other words I'm a newb) ...
For some reason I can't seem to use a function defined in a controller in another controller.
Here's the function in my MessagesController.cs file:
public List<Message> GetMessagesById(string username)
{
return db.Messages.Where(p => p.user == username).ToList();
}
When I try to reference it:
using LemonadeTrader.Models;
using LemonadeTrader.Controllers; // added this to pull the Messages::getMesssagesById
...
ViewBag.messages = lemondb.Messages.GetMessagesById(Membership.GetUser().ProviderUserKey.ToString());
I get something along the lines of lemondb.Messages does not contain a method called GetMesssagesById.
How do I reference it?
You shouldn't be linking controller methods like this, not to mention that controllers shouldn't be performing data access directly. I would recommend you externalizing this function into a separate class/repository which could be used by both controllers.
Example:
public class MessagesRepository
{
public List<Message> GetMessagesById(string username)
{
return db.Messages.Where(p => p.user == username).ToList();
}
}
and then:
public class FooController: Controller
{
public ActionResult Index()
{
var db = new MessagesRepository()
ViewBag.messages = db.GetMessagesById(Membership.GetUser().ProviderUserKey.ToString());
return View();
}
}
public class BarController: Controller
{
public ActionResult Index()
{
var db = new MessagesRepository()
ViewBag.messages = db.GetMessagesById(Membership.GetUser().ProviderUserKey.ToString());
return View();
}
}
OK, that's the first step. This code could be improved by decoupling the controllers from the repository by introducing an abstraction for this repository:
public interface IMessagesRepository
{
List<Message> GetMessagesById(string username);
}
public class MessagesRepository: IMessagesRepository
{
public List<Message> GetMessagesById(string username)
{
return db.Messages.Where(p => p.user == username).ToList();
}
}
then you could use constructor injection for those controllers:
public class FooController: Controller
{
private readonly IMessagesRepository _repository;
public class FooController(IMessagesRepository repository)
{
_repository = repository;
}
public ActionResult Index()
{
ViewBag.messages = _repository.GetMessagesById(Membership.GetUser().ProviderUserKey.ToString());
return View();
}
}
public class BarController: Controller
{
private readonly IMessagesRepository _repository;
public class BarController(IMessagesRepository repository)
{
_repository = repository;
}
public ActionResult Index()
{
ViewBag.messages = _repository.GetMessagesById(Membership.GetUser().ProviderUserKey.ToString());
return View();
}
}
finally you would configure your DI framework to pass the corresponding implementation into those controllers.
I would also recommend you replacing this ViewBag with a strongly typed view model:
public class MyViewModel
{
public List<Message> Messages { get; set; }
}
and then:
public ActionResult Index()
{
var model = new MyViewModel
{
Messages = _repository.GetMessagesById(Membership.GetUser().ProviderUserKey.ToString())
};
return View(model);
}
Place GetMessageById (and all other methods needed for accessing messages) to separate class and use the class everywhere you need to get Message data.
MessageService service = new MessageService();
ViewBag.messages = service.GetMessagesById(...);