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 to programmatically get Azure Service Bus Relay details (C#)?
The type or namespace name 'ThreadPoolTimer' could not be found
Join IQueryable with List on object from list
Exporting gridview with paging
Is it possible to pin a text on the top of the console c# [duplicate]
How to read simultaneously by several COM ports
How to delete rows with same value in datagridview
How to passing value to textbox in second form when object has been lunched
Make my datepicker required and remove it after selecting a date in c#
Microsoft Graph. DriveItem Id format?
DateTime parsing - unexpected result
Measuring mb sent per second with C# sockets? (Multithread)
C# inheritance multiple for different children
IList to JSON fails
Convert to Nested JSON C#
Sending List<Object> WCF POST

Categories

HOME
spring-boot
gulp
youtube-api
algolia
macros
stanford-nlp
sql-server-2014
compression
process
snappy
windows-server-2008
mifare
hiveql
esxi
mailchimp
atlassian-fisheye
webpack-dev-server
olap
wowza
mamp
solidity
k-means
openam
civicrm
beacon
hl7-fhir
single-page-application
android-wifi
core-animation
symlink
mex
jboss-arquillian
undo
ibm-bpm
log4net-configuration
qt-designer
rtos
webclient
oracle-bpm-suite
const
libconfig
cowboy
julia-jump
mixed-models
pyexcel
superclass
text-extraction
bootstrap-carousel
synchronized
jenkins-2
serverless-architecture
jcifs
hellosign
cc
grib
chain
dynatable
dbi
jspx
database-administration
razorengine
sqlxml
ewam
clear
jain-sip
page-flipping
first-order-logic
uinavigationitem
nmock
page-refresh
copy-on-write
mathics
iphone-6
drools-guvnor
ant-contrib
pthreads-win32
android-jack-and-jill
netbeans-plugins
grunt-contrib-imagemin
ia-32
typography
bho
gwt2
cloudmade
vline
django-tinymce
linqdatasource
yii-components
inserthtml
capitalization
recess
service-layer
method-call
designated-initializer
n2
llblgen
virtual-destructor
mysql-pconnect
zend-acl

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