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

threading timer not working, why?
Why doesn't C# volatile protect write-read reordering?
EditorTemplate and DateTimeOffset not working in MVC4
ftp file download working on localhost but not working on server
Million iterations per second
Merge Dll to Assembly or Embed in Resource - which is Better?
Can I use Sharp Architecture in an classic ASP.Net application or it is only for ASP.Net MVC?
How do I set the owner of a message queue?
Parallel Foreach vs PLINQ [closed]
C# to Word Changing the value of Paragraph
Excel Interop: Fastest way to change color of portions of text in a huge range of cells
command prompt do not opens up when calling (.exe) console application from web application c#
IIS aways returns an empty page
How to change the row Selector in GridView in Win C#
Impossible to test whether Button.click event is null
Runspace & custom powershell

Categories

HOME
logging
url
mobile
salesforce
jenkins-pipeline
spss
bitbucket
coordinates
opc-ua
ms-application-insights
psexec
pdf-generation
qt4
genexus
vsixmanifest
oms
fine-uploader
openscad
google-street-view
descriptor
turn.js
monad-transformers
opengraph
matlab-gui
devexpress-mvc
bootstrap-accordion
waterfall
formtastic
drombler-fx
dynamic-memory-allocation
pypy
drawrect
intermec
boost-log
opencsv
wordpress-rest-api
apache-falcon
perf
gstreamer-1.0
office-interop
keychain
mixed-models
aspnetboilerplate
smooth-streaming
android-doze-and-standby
spring-webflow-2
anonymous-function
evaluation
google-cloud-shell
vertex
dynamic-linking
richtext
android-vectordrawable
spring-cloud-aws
timex
nls
turbolinks
android-tabs
easy68k
papyrus
visual-web-developer
rowname
jde
paypal-subscriptions
oryx
jersey-test-framework
ewam
bioconductor
angular-promise
commercetools
serial-communication
database-project
cyberduck
sparkcore
strcpy
conkeror
caption
cordova-3
iphone-6
mind-manager
react-os
formbuilder
switchpreference
atg-dynamo
angular-file-upload
webshim
pidgin
sqldatasource
db2-connect
php-amqplib
scidb
misfire-instruction
extensibility
proj4
ntdll
qt5.1
idoc
jquery-ui-map
erlide
mvcmailer
fileoutputstream
clgeocoder
windows-xp-embedded
cpack
quazip
norton
marathontesting
chars
qprocess
helios
ffdshow
expander
weak-typing

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