Mock a Property in BaseClass - dependency-injection

I am trying to write some unit tests for an old system.
consider that I have a base class and a service like this :
public class BaseService
{
[Dependency]
public IBaseInterface _mybaseInterface { get; set; }
}
public class MyService : BaseService, IMyService
{
private readonly ISomeOtherInterface _myOtherInterface;
public MyService(ISomeOtherInterface myOtherInterface)
{
_myOtherInterface = myOtherInterface;
}
}
public class MyOtherService
{
private readonly IMyService _myservice;
public MyService(IMyService myservice)
{
_myservice = myservice
}
}
Question 1:
I am writing test for the MyOtherService class and I have to mock the IMyservice but I dont know how can I mock the interfaces in the base clas.
Question 2:
does converting the injection of the BaseService to constructor injection help me to mock the Myservice class dependencies ?

Related

Dependency Injection - Unity Constructor injection not working, only getter setter injection

I am having issues with Unity Dependency Injection. When I try to use constructor injection, my injected services stay empty/null.
public UserService(IUnitOfWorkIntranet unitOfWork, IUserRepository userRepository)
{
mappingToDomainModel = IntranetMappingToDomainModel.GetMappingToDomainModelInstance;
IntranetAutoMapperConfiguration autoMapper = IntranetAutoMapperConfiguration.GetAutoMapperConfigurationInstance;
unitOfWorkIntranet = unitOfWork;
userRepository = userRepository;
}
However, when I use a getter everything works just fine.
private IUserRepository _userRepository
{
get
{
return GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IUserRepository)) as UserRepository;
}
}
As far as I know it is configured properly in UnityConfig.cs
container.RegisterType<IUnitOfWorkIntranet, UnitOfWorkIntranet>();
container.RegisterType<IUserService, UserService>();
container.RegisterType<IUserRepository, UserRepository>();
Am I missing something here? Why is my constructor injection broken?
Any help is welcome, Regards!
There is a simple working example of the constructor injection using Unity:
public interface IUnitOfWorkIntranet { }
public class UnitOfWorkIntranet : IUnitOfWorkIntranet{}
public interface IUserRepository { }
public class UserRepository : IUserRepository{}
public interface IUserService{}
public class UserService : IUserService
{
public IUnitOfWorkIntranet UnitOfWork { get; }
public IUserRepository UserRepository { get; }
public UserService(IUnitOfWorkIntranet unitOfWork, IUserRepository userRepository)
{
UnitOfWork = unitOfWork;
UserRepository = userRepository;
}
}
Configuration and resolving:
var container = new UnityContainer();
container.RegisterType<IUnitOfWorkIntranet, UnitOfWorkIntranet>();
container.RegisterType<IUserService, UserService>();
container.RegisterType<IUserRepository, UserRepository>();
var service = (UserService)container.Resolve<IUserService>();

Interface usage on controller implementation

I'm using MVC pattern in my application. For each model class I have a controller one. All controller classes have a saveOrUpdate() method. I am wondering if this is enough to create an Interface which defines said method, and then all controller implements it.
Please note that saveOrUpdate() receive a model class as a parameter. So it would be something like UserController#saveOrUpdate(User user), CourseController#saveOrUpdate(Course course), AppleManager#saveOrUpdate(Apple apple).
I think what you need is generic repository which implements generic functionality for a given entity. I've recently started implementing Repository Pattern along with Unit of Work in my MVC projects. Here is how I do that.
MyDbContext.cs:
public class MyDbContext : DbContext
{
public MyDbContext() : base("name=DefaultConnection”)
{
}
public System.Data.Entity.DbSet<User> Users { get; set; }
public System.Data.Entity.DbSet<Course> Courses { get; set; }
}
Unit of Work:
public class UnitOfWork : IUnitOfWork
{
//private variable for db context
private MyDbContext _context;
//initial db context variable when Unit of Work is constructed
public UnitOfWork()
{
_context = new MyDbContext();
}
//property to get db context
public MyDbContext Context
{
//if not null return current instance of db context else return new
get { return _context ?? (_context = new MyDbContext()); }
}
//save function to save changes using UnitOfWork
public void Save()
{
_context.SaveChanges();
}
}
Generic Repository:
public class RepositoryBase<T> : IRepositoryBase<T> where T : class
{
protected readonly IUnitOfWork _unitOfWork;
private readonly IDbSet<T> _dbSet;
public RepositoryBase(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
_dbSet = _unitOfWork.Context.Set<T>();
}
public virtual void Save()
{
_unitOfWork.Save();
}
public virtual void Add(T entity)
{
_dbSet.Add(entity);
_unitOfWork.Save();
}
//Similarly you can have Update(), Delete(), GetAll() implementation here
}
Entity Repository inheriting from generic repo:
public class UserRepository:RepositoryBase<User>,IUserRepository
{
public UserRepository(IUnitOfWork unitOfWork) : base(unitOfWork)
{
}
//Here you can also define functions specific to User
}
Controller:
public class UserController : Controller
{
private readonly IUserRepository _dbUserRepository;
public UserController(IUserRepository dbUserRepository)
{
_dbUserRepository = dbUserRepository;
}
// GET: /User/
public ActionResult Index()
{
var users = _dbUserRepository.GetAll();
return View(users.ToList());
}
}
create an interface
interface ISave
{
void Save(object obj);
}
now in your controller implement it.
public class AppleControler : Controller , ISave
{
public void Save(Object obj)
{
//you can cast your object here.
}
}
Option two
interface ISave<T>
{
void Save(T obj);
}
public class AppleControler : Controller , ISave<Apple>
{
public void Save(Apple obj)
{
}
}

Initialize Object Properties

I am injecting in my services a global Settings interface, as Singleton, using StructureMap:
public interface ISettings {
LoggerSettings Logger { get; }
} // ISettings
public class LoggerSettings {
public String Levels { get { return ConfigurationManager.AppSettings["Logger.Levels"]; } }
public const String Report = "team#xyz.com";
} // LoggerSettings
public class Settings : ISettings {
public LoggerSettings Logger { get; private set; }
} // Settings
And as SM configuration I have:
For<ISettings>().Singleton().Use<Settings>();
I am able to inject this object but when I check the injected object its property Logger is null ... How can I have SM to initialize the object properties?
Am I missing something?
You need a constructor on the Settings class that has a LoggerSettings parameter so that StructureMap can set the Logger property on creation.
If you for some reason can't/don't want to use Constructor injection you need to make the setter on the Logger property on the Settings class public and configure property injection in StructureMap.
TL;DR: make Settings look like this:
public class Settings : ISettings {
public Settings(LoggerSettings logger)
{
Logger = logger;
}
public LoggerSettings Logger { get; private set; }
}

MVC Base Controller and Ninject

I am implementing Ninject dependency injection in an existing MVC 2 application that uses a base controller that all controllers inherit to set navigation and other information needed by the master page. When I set a controller to inherit from the base controller, I get the following error: "...BaseController' does not contain a constructor that takes 0 arguments. How do I get around this error? I am new to Ninject and can't figure this out.
public class BaseController : Controller
{
private INavigationRepository navigationRepository;
private ISessionService sessionService;
public BaseController(INavigationRepository navigationRepository, IMembershipService membershipService, ISessionService sessionService)
{
this.navigationRepository = navigationRepository;
this.sessionService = sessionService;
}
}
public class HomeController: BaseController
{ ... }
Adding that ctor is one way
public class HomeController: BaseController
{
public HomeController(INavigationRepository navigationRepository, IMembershipService membershipService, ISessionService sessionService)
: base(navigationRepository, membershipService, sessionService) { }
}
or property injection
public class BaseController : Controller
{
[Inject]
public INavigationRepository navigationRepository { get; set; }
[Inject]
public ISessionService sessionService { get; set; }
}

Ninject not binding object in BaseController in MVC3

I just upgraded my MVC2 project to MVC3 and used the NuGet library package reference to install ninject. This created an appstart class and i used the following code to inject my IMembershipService class.
public static void RegisterServices(IKernel kernel) {
kernel.Bind<IMembershipService>().To<AccountMembershipService>();
}
This works great with my HomeController, for example.
public class HomeController : Controller
{
public IMembershipService MembershipService { get; set; }
public HomeController() : this(null) { }
public HomeController(IMembershipService service)
{
MembershipService = service;
}
HOWEVER, I am using a BaseController. Nearly the same code in the base class no longer works.
public class BaseController : Controller
{
public IMembershipService MembershipService { get; set; }
public UserService UserService { get; set; }
public BaseController() : this(null, null) { }
public BaseController(IMembershipService service, UserService userService)
{
MembershipService = service;
UserService = userService ?? new UserService();
}
If I break in the constructor of the base controller, service is just NULL. I have never used Ninject for IOC so perhaps the answer is obvious, but why will it not inject my AccountMembershipController in the base class like I want it to? I don't see what is different, although i realize the extra level of inheritance may be messing with Ninject somehow.
Your HomeController dervices from Controller, not BaseController? Also, you have a default constructor for BaseController that sets things as null. Why do you have that at all? I'd start by getting rid of those default constructors. You shouldn't need any default constructors.
I ran into this same problem myself. Assuming your code looks like this:
public HomeController : BaseController
{
}
public BaseController : Controller
{
public IMembershipService MembershipService { get; set; }
public MembershipService() { }
public MembershipService(IMembershipService service)
{
MembershipService = service;
}
}
For some reason, Ninject thinks that HomeController only has one constructor, the default parameterless one. When you put everything in HomeController, it can find the injectable constructor, but factor it out into a base class and for some reason it won't look in the base class to see if there are any overloaded constructors. There are two fixes for this:
Remove the default constructor. This is my preferred solution because it forces the constructor to be injected (like when you create the controller manually when unit testing), but the downside is that you have to implement the constructor in all your subclasses.
Keep the default constructor, but add the [Inject] attribute to all your injectable properties:
public BaseController : Controller
{
[Inject] public IMembershipService MembershipService { get;set; }
// rest is the same
}
Ninject will inject the properties correctly this way, but be aware that Ninject will call the parameterless constructor.

Resources