c#


How to solve base Controller dependency injection for testing purposes?


I have implemented my mvc base controller called DefaultController using dependency injection pattern in order to be able to construct test cases. Example below:
public class DefaultController : Controller
{
protected readonly ISessionHelper _sessionHelper;
string _thisUserOpenID;
protected IUsersRepository _UserRepository;
...
public DefaultController()
{ } //not for testing
public DefaultController(ISessionHelper session, IUserRepository repo)
{
_sessionHelper=session;
_UserRepository = repo;
}
}
Then I have my controllers using this controller, homecontroller, usercontroller, etc.
Now, building some test cases I found myself in a situation where I don't know how to actually use the injection dependency pattern.
[TestMethod]
public void Welcome_Message_In_ViewData_Has_Coockie_User_Display_Name()
{
// Below I want to insert FakeRepositories using
//ISessionHelper and so on. but the constructor
//for homecontroller don't have it.
HomeController controller = new HomeController();
Any ideas?
Your HomeController needs to have a matching "injectable" constructor, which would then call the base constructor.
public HomeController(ISessionHelper session, IUserRepository repo)
: base(session, repo)
{
}
Now, in your test, you would create your HomeController using that constructor, and pass in a mocked up session and user repository. Speaking of mocking, you might also be interested in Scott Hanselman's MvcMockHelpers classes, with code for many popular mocking frameworks.
I don't see why you have two constructors. You should only have one, get rid of the constructor with no parameters. Using a DI framework like Castle Windsor, or my preferred one, Autofac will handle all of this for you. Then as far as testing is concerned use something like Moq. Ie
public DefaultController(ISessionHelper session, IUserRepository repo)
{
_sessionHelper = session;
_UserRepository = repo;
}
Register DefaultController, ISessionHelper and IUserRepository with your DI framework. Something along the lines of:
Register(new DefaultController()); (it is something like that in Autofac)
Register<SessionHelper>().As<ISessionHelper>();
Register<UserRepository>().As<IUserRepository>();
That way, you can pull DefaultController from the container and the DI framework will inject the two parameters for you. I wrap up a static method to access my DI container, it looks like:
var controller = IoC.Resolve<DefaultController>();
Basically head over to Autofac and have a look. There's also a web module for registering your Controllers for you.
Then for testing just use Moq, or find some form of "AutoMocker" (google it). I would do:
var session = new Mock<ISessionHelper>();
var repo = new Mock<IUserRepository>();
repo.Setup(s => s.FindById(123)).Returns(new User());
var conroller = new DefaultController(session.Object, repo.Object);
controller.Execute();
Also ewww repositories. With .Net and generics etc... just create yourself an nice ISession.
var session = IoC.Resolve<ISession>();
var user1 = session.Get<User>(123);
var user2 = session.Get<User>(u => u.Username == "admin");
session.Update(user3);
Means you only need to pass in one thing and you can use it for whatever. Rather than having to pass in sometimes many repositories. Also sets you up nicely for the Unit Of Work pattern.

Related Links

How do I get the network interface and its right IPv4 address?
How can I delete a directory in a Zip file using .NET?
receiving string from c# to Java mistakes
No endpoint listening wcf/rest
How to add NT AUTHORITY\IUSR to Administrators group
Combobox in Syncfusion XlsIO
Creating a Strong Name dynamically, without Sn.exe
Why is my locally declared variable not being recognized in the finally block?
Comparing two different types with Entity Framework
loginview shows “welcome system-name/administrator” and logout for the first time page load
How to abort another thread in .NET, when said thread is executing Console.ReadLine?
OrderBy / ThenBy looping - nested Lists in C#
How to login external web site from asp.net web page? [closed]
ListPicker for WPF?
How to notify user of new message?
WPF Treeview Bindings

Categories

HOME
qlikview
swift3
ns2
openacc
cxf
webvr
azure-resource-manager
glympse
multipartform-data
python-3.4
samsung-gear-s2
annyang
segmentation-fault
oms
point-of-sale
android-notifications
repeater
google-closure-compiler
simd
vivado-hls
gpo
jboss-arquillian
textview
ios-autolayout
snapkit
javax
gitosis
mkdir
hippocms
mybatis-generator
linkurious
contenteditable
weld
runner
hdpi
nao-robot
spring-cloud-bus
sharpssh
blackberry
cardview
esprima
directinput
optional-parameters
papyrus
alfred
universe
mate-desktop
patching
avi
nd4j
android-progressbar
stdlist
alchemy
self-join
jain-sip
bootstrap-tabs
borland-c++
tokudb
litedb
euro
cakephp-2.6
cl.exe
applinks
static-files
grunt-contrib-connect
cocos2d-x-2.x
livescript
sat4j
drawable
isl
visual-studio-setup-proje
ant-contrib
enquire.js
email-headers
new-operator
starling-framework
code-complete
xcode5.1
grunt-contrib-imagemin
google-oauth-java-client
objectdatasource
typography
asp.net-4.0
exi
vline
cron4j
screensharing
invalidoperationexception
mail-gem
m3u
apache-commons-email
lwp
llblgen
chars
hp-trim
dynamic-scope
ihtmldocument2
scala-designer
zend-acl
moores-law

Resources

Mobile Apps Dev
Database Users
javascript
java
csharp
php
android
MS Developer
developer works
python
ios
c
html
jquery
RDBMS discuss
Cloud Virtualization
Database Dev&Adm
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App