Removing Convert.ToDecimal Dependency (Dependency Injection) - c#

I am currently learning dependency injection to create more maintainable code with MVC. I am already injecting a model and a calculator service to my controller instead of having a to new up dependency.
I have a few Convert.ToDecimal calls in my constructor, and didn't know if I needed to worry about using dependency injection to remove the static method call which is a DI design smell. Is removing that going too far?
private readonly ICalculationService _calculation;
private readonly ICalculatorModelService _calculatormodel;
public CalculatorController(ICalculationService calculation,
ICalculatorModelService calculatormodel) {
_calculation = calculation;
_calculatormodel = calculatormodel;
}
public ActionResult Index() {
var model = _calculatormodel;
return View(model);
}
public PartialViewResult Calculate(string submit, string txtValue,
string value1) {
var model = _calculatormodel;
if (submit == "+")
{
if (Session["value1"] == null)
Session.Add("value1",Convert.ToDecimal(txtValue));
else
Session["value1"] = value1;
}
else if (submit == "=")
{
if (Session["value1"] == null)
Session.Add("value1", 0);
model.Result = _calculation.Calculate(Convert
.ToDecimal(Session["value1"]), Convert.ToDecimal(txtValue));
}
return PartialView("_Calculator", model);
}

If I understand the question, you are worried about the static call of Convert and you ask if this class should also be injected.
If that's the case, you don't have too. Same goes for similar static calls like Math. methods etc.
The rule I follow for such .NET helper calls is, if the call is deterministic, i.e. always returning same output for the same input, then go ahead call it (anyway you depend on .NET framework, right?). But if the call is non deterministic, like Datetime.Now or use of Random class, then I inject these dependencies (which makes code more testable, of course)

Related

Unit Testing a controller that uses windows authentication

-------Please see updates below as I now have this set up for dependency injection and the use of the MOQ mocking framework. I'd still like to split up my repository so it doesn't directly depend on pulling the windowsUser within the same function.
I have a Web API in an intranet site that populates a dropdown. The query behind the dropdown takes the windows username as a parameter to return the list.
I realize I don't have all of this set up correctly because I'm not able to unit test it. I need to know how this "should" be set up to allow unit testing and then what the unit tests should look like.
Additional info: this is an ASP.NET MVC 5 application.
INTERFACE
public interface ITestRepository
{
HttpResponseMessage DropDownList();
}
REPOSITORY
public class ExampleRepository : IExampleRepository
{
//Accessing the data through Entity Framework
private MyDatabaseEntities db = new MyDatabaseEntities();
public HttpResponseMessage DropDownList()
{
//Get the current windows user
string windowsUser = HttpContext.Current.User.Identity.Name;
//Pass the parameter to a procedure running a select query
var sourceQuery = (from p in db.spDropDownList(windowsUser)
select p).ToList();
string result = JsonConvert.SerializeObject(sourceQuery);
var response = new HttpResponseMessage();
response.Content = new StringContent(result, System.Text.Encoding.Unicode, "application/json");
return response;
}
}
CONTROLLER
public class ExampleController : ApiController
{
private IExampleRepository _exampleRepository;
public ExampleController()
{
_exampleRepository = new ExampleRepository();
}
[HttpGet]
public HttpResponseMessage DropDownList()
{
try
{
return _exampleRepository.DropDownList();
}
catch
{
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
}
}
}
UPDATE 1
I have updated my Controller based on BartoszKP's suggestion to show dependency injection.
UPDATED CONTROLLER
public class ExampleController : ApiController
{
private IExampleRepository _exampleRepository;
//Dependency Injection
public ExampleController(IExampleRepository exampleRepository)
{
_exampleRepository = exampleRepository;
}
[HttpGet]
public HttpResponseMessage DropDownList()
{
try
{
return _exampleRepository.DropDownList();
}
catch
{
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
}
}
}
UPDATE 2
I have decided to use MOQ as a mocking framework for unit testing. I'm able to test something simple, like the following. This would test a simple method that doesn't take any parameters and doesn't include the windowsUser part.
[TestMethod]
public void ExampleOfAnotherTest()
{
//Arrange
var mockRepository = new Mock<IExampleRepository>();
mockRepository
.Setup(x => x.DropDownList())
.Returns(new HttpResponseMessage(HttpStatusCode.OK));
ExampleController controller = new ExampleController(mockRepository.Object);
controller.Request = new HttpRequestMessage();
controller.Configuration = new HttpConfiguration();
//Act
var response = controller.DropDownList();
//Assert
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
I need help testing the DropDownList method (one that does include code to get the windowsUser). I need advice on how to break this method apart. I know both parts shouldn't been in the same method. I don't know how to arrange splitting out the windowsUser variable. I realize this really should be brought in as a parameter, but I can't figure out how.
You usually do not unit-test repositories (integration tests verify if they really persist the data in the database correctly) - see for example this article on MSDN:
Typically, it is difficult to unit test the repositories themselves, so it is often better to write integration tests for them.
So, let's focus on testing only the controller.
Change the controller to take IExampleRepository in its constructor as a parameter:
private IExampleRepository _exampleRepository;
public ExampleController(IExampleRepository exampleRepository)
{
_exampleRepository = exampleRepository;
}
Then, in your unit tests, use one of mocking frameworks (such as RhinoMock for example) to create a stub for the sole purpose of testing the controller.
[TestFixture]
public class ExampleTestFixture
{
private IExampleRepository CreateRepositoryStub(fake data)
{
var exampleRepositoryStub = ...; // create the stub with a mocking framework
// make the stub return given fake data
return exampleRepositoryStub;
}
[Test]
public void GivenX_WhenDropDownListIsRequested_ReturnsY()
{
// Arrange
var exampleRepositoryStub = CreateRepositoryStub(X);
var exampleController = new ExampleController(exampleRepositoryStub);
// Act
var result = exampleController.DropDownList();
// Assert
Assert.That(result, Is.Equal(Y));
}
}
This is just a quick&dirty example - CreateRepositoryStub method should be of course extracted to some test utility class. Perhaps it should return a fluent interface to make the test's Arrange section more readable on what is given. Something more like:
// Arrange
var exampleController
= GivenAController()
.WithFakeData(X);
(with better names that reflect your business logic of course).
In case of ASP.NET MVC, the framework needs to know how to construct the controller. Fortunately, ASP.NET supports the Dependency Injection paradigm and a parameterless constructor is not required when using MVC unity.
Also, note the comment by Richard Szalay:
You shouldn't use HttpContext.Current in WebApi - you can use base.User which comes from HttpRequestBase.User and is mockable. If you really want to continue using HttpContext.Current, take a look at Mock HttpContext.Current in Test Init Method
One trick that I find very useful when trying to make old code testable when said code is accessing some global static or other messy stuff that I can't easily just parameterize is to wrap access to the resource in a virtual method call. Then you can subclass your system under test and use that in the unit test instead.
Example, using a hard dependency in the System.Random class
public class Untestable
{
public int CalculateSomethingRandom()
{
return new Random().Next() + new Random().Next();
}
}
Now we replace var rng = new Random();
public class Untestable
{
public int CalculateSomethingRandom()
{
return GetRandomNumber() + GetRandomNumber();
}
protected virtual int GetRandomNumber()
{
return new Random().Next();
}
}
Now we can create a testable version of the class:
public class Testable : Untestable
{
protected override int GetRandomNumber()
{
// You can return whatever you want for your test here,
// it depends on what type of behaviour you are faking.
// You can easily inject values here via a constructor or
// some public field in the subclass. You can also add
// counters for times method was called, save the args etc.
return 4;
}
}
The drawback with this method is that you can't use (most) isolation frameworks to implement protected methods (easily), and for good reason, since protected methods are sort of internal and shouldn't be all that important to your unit tests. It's still a really handy way of getting things covered with tests so you can refactor them, instead of having to spend 10 hours without tests, trying to do major architectual changes to your code before you get to "safety".
Just another tool to keep in mind, I find it comes in handy from time to time!
EDIT: More concretely, in your case you might want to create a protected virtual string GetLoggedInUserName(). This will technically speaking keep the actual call to HttpContext.Current.User.Identity.Name untested, but you will have isolated it to the simplest smallest possible method, so you can test that the code is calling the correct method the right amount of times with the correct args, and then you simply have to know that HttpContext.Current.User.Identity.Name contains what you want. This can later be refactored into some sort of user manager or logged in user provider, you'll see what suits best as you go along.

Entity Framework Code First using context in Controller

I finally got my code to work as intended but I cant figure out why the previous way I had it setup didn't work. I kept getting a null reference exception, specifically, "Object reference not set to an instance of an object.. What I want to do is to pass in a readonly BlogDb model and use the LINQ queries throughout the controller, but it seems like every controller action I have to pass in the BlogDb model.
private readonly BlogDb model;
public PostsController(BlogDb model)
{
this.model = model;
}
public ActionResult Index()
{
return View();
}
[ValidateInput(false)]
public ActionResult Update(int? id, string title, string body, DateTime date, string tags)
{
var _db = new BlogDb();
if (!IsAdmin)
{
RedirectToAction("Index");
}
if (ModelState.IsValid)
{
Post post = GetPost(id);
post.Title = title;
post.Body = body;
post.Date = date;
post.Tags.Clear();
tags = tags ?? string.Empty;
string[] tagNames = tags.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string tagName in tagNames)
{
post.Tags.Add(GetTag(tagName));
}
if (!id.HasValue || id == 0)
{
_db.Posts.Add(post);
}
_db.SaveChanges();
return RedirectToAction("Details", new { id = post.Id });
}
return View();
}
public ActionResult Edit(int? id)
{
Post post = GetPost(id);
var tagList = new StringBuilder();
foreach (Tag tag in post.Tags)
{
tagList.AppendFormat("{0}", tag.Name);
}
ViewBag.Tags = tagList.ToString();
return View(post);
}
public Tag GetTag(string tagName)
{
//return model.Tags.FirstOrDefault(x => x.Name == tagName) ?? new Tag() { Name = tagName };
return new Tag() { Name = tagName };
}
private Post GetPost(int? id)
{
if (id.HasValue && id != 0)
{
return model.Posts.FirstOrDefault(x => x.Id == id);
}
return new Post();
}
When I had the following snippit of code it kept throwing a object instance exception when I try to SaveChanges.
if (!id.HasValue || id == 0)
{
model.Posts.Add(post);
}
model.SaveChanges();
So I had to end up throwing a local instance of the model and use it that way.
var _db = new BlogDb();
And further down
if (!id.HasValue || id == 0)
{
_db.Posts.Add(post);
}
_db.SaveChanges();
Am I just misunderstanding how to work with the database context?
Also what is the purpose of making a constructor pass in the model?
private readonly BlogDb model;
public PostsController(BlogDb model)
{
this.model = model;
}
public PostsController()
{
}
You have 2 constructors - only one of them sets the model field. The default controller factory will only ever call the default, parameterless constructor, leaving the parameterized one unused (and thus, the model field remains null).
That's why you get a NullReferenceException when you access model: the field's reference was never assigned!
This:
var _db = new BlogDb();
Is a sloppy fix. Instead, chain your constructors:
public PostsController()
: this(new BlogDb())
{
}
public PostsController(BlogDb model)
{
this.model = model;
}
This way the model field will be assigned regardless of which constructor is used to create the controller.
Note that this is called bastard injection, a dependency-injection anti-pattern. Either you DI, or you don't - in other words, if you're going to be using the default controller factory, do this instead:
public PostsController()
{
this.model = new BlogDb();
}
or even:
private readonly BlogDb model = new BlogDb();
And then you can remove all constructors... and you have a tightly coupled piece of code.
One good (excellent) read on the subject, is Dependency Injection in .NET, by Mark Seemann.
IDisposable
Your BlogDb inheriting EF's DbContext, it implements the IDisposable interface, which means you need to think of how you're going to call Dispose() on that instance.
By making it an instance-level private field [and not doing proper dependency injection], you've made your life very complicated.
You want an instance per request - because you'll want that resource to be in-scope only as long as it needs to be, and that means a new instance for each ActionResult method; something like this:
IEnumerable<Post> posts;
using (var context = new BlogDb())
{
posts = context.Posts.ToList();
return View(posts);
}
The using block ensures IDisposable.Dispose() will get called on context. The only other option, is to call context.Dispose() manually; if context is some private readonly BlockDb _context; field instead, things will only go well until the disposed context is used again.
As a general rule of thumb, the object that is responsible for creating an IDisposable instance, is also responsible for disposing it.
Constructor Injection
Now if you implement your own IControllerFactory use an IoC container, and wire it up in global.asax, it's a different story.
Now the object that's responsible for instantiating the disposable context is also responsible for disposing it, and can do so once per request, i.e. to inject a new instance, through the constructor, at each request - and then dispose it.
That's when you have an instance-level private readonly BlogDb _context; constructor-injected by the IoC container - because you know that whoever is giving you that instance, will be disposing it properly (because you've set it up that way).
You won't need the default constructor anymore, so keep things simple with a single constructor that ends up statically documenting every dependency the class has, through the constructor signature:
private readonly BlogDb _context;
public PostsController(BlogDb context)
{
_context = context;
}
The foundation of dependency injection, is to depend on abstractions, not implementations. By doing that...
private readonly IPostsService _service;
public PostsController(IPostsService service)
{
_service = service;
}
You're now free to inject a BlogDb (given BlogDb : IBlogService)... or anything else that implements that interface, perhaps a mock implementation, that make it possible to write unit tests that can cover all controller actions, without hitting the database.
By depending directly on BlogDb, the controller is tied to the specific implementation details of that class; it's tightly coupled. By depending on an abstraction, loose coupling is achievable.
The model field will be null because you haven't told MVC how it should handle controllers with non-default constructors. MVC uses something called a controller factory, that by default will pick a parameterless constructor, if it exists, when creating your controllers. If you remove the parameterless contructor, you will probably get an exception.
If you want to be able to "inject" parameters into your controllers, you need to do one of these:
Implement the IControllerFactory interface and set it using the ControllerBuilder.Current.SetControllerFactory method.
implement the IDependencyResolver interface and set it using the DependencyResolver.SetResolver method.
Implementing these interfaces is usually done using an IoC container. There's existing implementations for the most popular ones out there, that you can just plug in and go. I suggest your read more about MVC and Dependency Injection.

Testing CRUD class.

I have some issue. Im writing some unit test in my project but i don't know how to test my CRUD methods.. Maybe they are not testable ;/
This is one of my methods:
public static void IncrementInvalidLoginColumn(string login)
{
User user;
using (DTContext context = new DTContext())
{
try
{
user = context.Users.Where(u => u.Login.CompareTo(login) == 0).FirstOrDefault();
if (user.InvalidLogins < 3)
{
user.InvalidLogins = user.InvalidLogins + 1;
}
context.SaveChanges();
}
catch
{
}
}
}
Maybe someone will have idea what should i do.
It depends on what you mean by "unit" test. If you don't want your test to hit the database then your method is not testable (or at least not without some refactoring).
If hitting the database is acceptable (which would actually be an integration test) then you can definitely test your method.
Here are some steps:
1. Arrange the initial data. You use an instance of the DTContext directly in the test to put the system in a predefined state (basically you write some user records in the database)
You run the method you want to test (which in fact uses its own instance of the DTContext)
You use DTContext again to read the user information directly from the database and assert that the InvalidLogins property has incremented.
You need to make sure you delete any data that you put in manually.
This is the gist of DI:
public class Example {
private IDatabaseGateway myDatabase;
public Example(IDatabaseGateway myDb) {
myDatabase = myDb;
}
public void DoStuff() {
...
myDatabase.GetData();
...
}
}
You give your business class an abstraction of the database via the constructor, that is you inject your dependencies in the class that needs them.
Once you have this in place, in production code you pass in the constructor a concrete instance of IDatabaseGateway that goes to the actual database.
In the case of a unit test you pass it a mock instance of the same interface. The mock is a special object that you can setup/configure to return what you want. Various libraries exist for mocking (an easy one is Moq).
However without modifying your code too much, it is better to stick with integration testing that hits the database. It will give you a simple and valid test.
Especially since there are some pitfalls in mocking the DbContext in EF (ex. some queries may not work when you will use them in production, testing updates in EF with mocks is a bit trickier).
Ok so i read all of your posts and they was very helpful.
I use MOQ framework and this is example how i do it.
This is how Liviu M. told me to do for example:
public class CRUDclass
{
private DTContext _context;
public CRUDclass(DTContext myObj)
{
_context = myObj;
}
}
We have CRUD Class which are doing operations directly on our database. We have constructor with one argument and private field. This our context :)
This is (for example) my method in CRUDclass:
public bool AddUser(User user)
{
try
{
_context.Users.Add(user);
_context.SaveChanges();
return true;
}
catch
{
return false;
}
}
Ovecourse he have our DTContext class witch DBSet becouse i using entity framework. And after that i am able to write some test method:
[TestMethod]
public void Should_Add_User()
{
var mockSet = new Mock<DbSet<User>>();
var mockContext = new Mock<DTContext>();
mockContext.Setup(m => m.Users).Returns(mockSet.Object);
var usrCRUD = new UserCRUD(mockContext.Object);
var usr = new User();
usr.Login = "Login_Name";
usr.Email = "loginName#test.com";
usr.Password = "***";
usr.InvalidLogins = 0;
usr.RememberID = 0;
usrCRUD.AddUser(usr);
mockSet.Verify(m => m.Add(It.Is<User>(arg => arg.Login == "Login_Name")));
mockContext.Verify(m => m.SaveChanges(), Times.Once());
}
At first a have to set my fake object (Mock>).
This test method checks if our user was added to Mock :)
I hope it can help somebody, if anything will be unclear please write a question :)
The idea of unit tests is to test your ifs, switches, etc., not the database operations.
In your case you need an interface that is an abstration of DTContext. In the simplest case it might look as the following.
public interface IObjectContext : IDisposable
{
IEnumerable<User> Users { get; }
}
In more complicated cases you may need to use IQueryable<T> or IObjectSet<T> instead of IEnumerable<T>.
Add a partial class declaration of DTContext and make it implement IObjectContext. Add a constructor to the class that contains the method IncrementInvalidLoginColumn with a parameter of type IObjectContext. Now you can inject any instance of IObjectContext instead of creating it in your class. This instance can be a DTContext or a mock for testing. Your class is ready to be tested without connection to a real database.
NB. In case of instances of IDisposable it's better to inject a Func<IObjectContext> instead of IObjectContext. Then you can create an instance for each operation and dispose it immediately after.
If there are CRUD operations in your code then I will recommend to use MOQ framework for unit testing. Below links are quite helpful:
Quick Start
Code Project
Ideally you would inject your DTContext rather than creating a new one every time that the method is called. That way you could mock that object in your unit test and verify that it is called as expected.
Your constructor would look something like:
private readonly IDTContext _context;
public CrudClass(IDTContext context)
{
_context = context
}
With your method now looking like
public static void IncrementInvalidLoginColumn(string login)
{
User user;
try
{
user = _context.Users.Where(u => u.Login.CompareTo(login) == 0).FirstOrDefault();
if (user.InvalidLogins < 3)
{
user.InvalidLogins = user.InvalidLogins + 1;
}
_context.SaveChanges();
}
catch
{
// Handle errors
}
}
And then in your test, if you were using a framework like Moq, you would basically script how that object would behave and test against that. For instance, setting up the mocked IDTContext to always return the same user for your Users collection and SaveChanges() method will write the number of invalid logins to a variable that you could then test against.

Removing boilerplate from ASP.NET MVC actions

I have something like this in almost every action:
public ActionResult Show(int object_id)
{
Object obj = ObjectRepository.ById(object_id);
if (obj == null)
{
throw new HttpException(404);
}
if (obj.SomeCheck)
{
throw new HttpException(403);
}
// processing
}
Question is how to move object getting (and throwing http exceptions) away from action and have something like this:
public ActionResult Show(Object obj)
{
// processing
}
UPD: Can't change ObjectRepository and model itself, it's used not only with ASP.NET but in other parts of the project.
One option is to refactor your boilerplate into a private method:
private object GetItem(object obj) {
Object obj = ObjectRepository.ById(object_id);
if (obj == null) {
throw new HttpException(404);
}
if (obj.SomeCheck()) {
throw new HttpException(403);
}
return obj;
}
Then:
public ActionResult Show(int object_id) {
object obj = GetItem(object_id);
// processing
}
As others have suggested you could write filters or invoke an AOP framework like PostSharp.
However, that might be a tall order for some. You might want to consider writing something simple, maintainable and fairly readable, that everyone on the team can immediately understand:
public ActionResult Show(int object_id)
{
SomeClass obj = Require<SomeClass>(object_id, assumption: o => o.SomeCheck);
// processing
}
//Perhaps: put this in a base controller or other common class
private object Require<T>(int id, Func<object, bool> assumption) where T : class
{
var o = ObjectRepository.ById(object_id) as T;
//Result is required
if (o == null) {
throw new HttpException(404);
}
//Verify assumption
if (!assumption(o)) {
throw new HttpException(403);
}
return o;
}
You might look at
Writing a custom filter attribute such as an AuthorizationAttribute or ValidateInputAttribute. They can be applied to the entire controller or to specify methods (actions). See http://msdn.microsoft.com/en-us/magazine/dd695917.aspx#id0070026 for an overview.
You might want to look at using PostSharp (Aspect-Oriented Programming framework) to inject suitable aspects into your methods.
Others have provided some good answers. Among them, I like the idea of using an action filter but unfortunately I don't believe it will work very well as you'll be forced to use property injection (or explicit instantiation - yuck!) for the repository, which I'd prefer to avoid. For this reason, I think a dedicated controller method is a better option.
I will throw one more idea in the hat, though.
You mentioned that you can't change ObjectRepository but you can always abstract it:
public class HttpObjectService /*: IObjectService */
{
private readonly /*I*/ObjectRepository _repository;
public HttpObjectService(/*I*/ObjectRepository repository)
{
if (repository == null) throw new ArgumentNullException("repository");
_repository = repository;
}
public Object ById(int id)
{
var obj = _repository.ById(id);
/* Check and throw HttpExceptions */
}
}
Then inject this into your controller. Whether or not you like the idea of a "web-specific" service that throws HttpExceptionsdirectly is a matter of taste but it is extremely reusable and, in this case, I believe it provides a cleaner separation of concerns than private validation methods in the controller.
The downside, of course, is that you're allowing your controller to delegate its responses (in the event of an error) directly to a third party. You may prefer your controller to have absolute control over this - that would be a reasonable criticism. In that case, you could always pass an ObjectValidator object into the constructor from the controller, which takes care of the validation. This would let your controller maintain control of what exceptions are thrown regardless of the service implementation.
You would have to be considerate of where this fits into your project architecture - it would probably belong in a separate assembly to your MVC project but one that is dedicated to web-based UIs.

Unit test method with mock DAL, but underlying method calls different (real) DAL

I'm trying to implement unit tests in my current project. After that I'll start developing using TDD further on in this project.
Yesterday I started making some tests and it wasn't as easy as it looks in theory/books.
At the moment I'm struggling with a specific scenario, which I know someone else must have worked with in the past also.
Some background information.
I've got a method called Add() in the class AddProduct. When a new object is passed to the Add method, there has to be made a new Item first, so I'll have to call the Add() method of the AddItem class first.
All of this code exists in the Business Layer. Off-course the real adding happens in the DAL, which is called from within my AddProduct and AddItem classes.
To get an idea, this is what I have so far:
public class AddProduct : Product<IDataAccessAdd<Entities.Product>>, IBusinessAdd<Entities.Product>
{
private readonly Business.IBusinessAdd<Entities.Item> _addItem;
public AddProduct() : base(new DataAccess.AddProduct())
{
_addItem = new AddItem();
}
public AddProduct(DataAccess.IDataAccessAdd<Entities.Product> dal, Business.IBusinessAdd<Entities.Item> itemBl) : base(dal)
{
_addItem = itemBl;
}
private Entities.Product _newProduct;
public bool Add(ref Product product, string user)
{
bool isAdded = false;
_newProduct = product;
if(AddNewItem(user))
{
isAdded = Dal.Add(product);
}
return isAdded;
}
private bool AddNewItem(string user)
{
var newItem = new Item();
bool isAdded = _addItem.Add(ref newItem, user);
_newProduct.Item = newItem;
return isAdded;
}
}
As you can see, I'm calling the AddNewItem from within the Add method.
The problem in this example is the constructor.
I'd like to have a constructor with 0 or 1 parameter, like so:
public AddProduct() : base(new DataAccess.AddProduct())
{
}
public AddProduct(DataAccess.IDataAccessAdd<Entities.Product> dal) : base(dal)
{
}
and the AddNewItem method like so (or something similar):
private bool AddNewItem(string user)
{
var newItem = new Item();
var addItem = new Business.AddItem();
bool isAdded = addItem.Add(ref newItem, user);
_newProduct.Item = newItem;
return isAdded;
}
But when doing this, the code executed in the AddNewItem method uses a 'real' DAL and I don't want that in a unit test. I solved this issue by adding a new parameter to the constructor, which can also create a mock DAL for the Business.Item class. However, I don't think this is the way to go.
In theory, you could get a constructor with 20 parameters, all used for unit testing. Not a very pretty sight.
A colleague of mine told me this could probably be solved using a Factory Method design pattern, but he wasn't sure that would be a best choice.
As I've never worked with the Factory Method design pattern, I don't feel very comfortable implementing it when unit testing is new to me also.
Any other suggestions which I could try?
There's two approaches you can use here.
Setup a IOC container specifically for testing. In this container you would configure the dal service to be your test or mock DAL service.
Wire-up your classes manually. In this case you would explicitly call the AddProduct constructor and pass in your test or mock DAL service.
The rationale behind this is that dependency injection allows you to create a sandbox to isolate and test a specific part of your code. The options above create that sandbox.

Categories