Scenario
We're developing a new MVC web project and we're trying to adhere to the Skinny Controller pattern as described in this article http://codebetter.com/iancooper/2008/12/03/the-fat-controller/
As part of one of our actions we are retrieving some navigation data (Menu structure) from the Cache.
Problem
I order to maintain the skinny controller pattern we'd like to have the cache check call in the ViewModel, which we have tried and we know works, using the following code.
var cachedCategories = (List<Category>)HttpContext.Current.Cache["Categories"];
if (cachedCategories == null) {
cachedCategories = _service.GetCategories().ToList<Category>();
HttpContext.Current.Cache["Categories"] = cachedCategories;
}
However when it comes to unit testing it we hit a problem. Since we are not directly passing the HttpContext into the ViewModel we have no idea how to go about mocking the HttpContext.
We're using Moq and while we have some options (one is to pass the context from the controller to the viewmodel at instantiation) those options require changing the code purely to make the tests work.
Does anyone have any suggestions?
mock the HttpContext is a huge work as it is one of the biggest object you will see in all your life so probably is better don't mock it.(http://volaresystems.com/Blog/post/Dont-mock-HttpContext.aspx)
Anyway you could use the one in MVCcontrib (http://www.codeplex.com/mvcContrib) the file MvcMockHelps shows how it is done.
Ultimately we choose to modify our code to allow for easier testing.
We accomplished this by passing the HttpContext to the ViewModel at instantiation as I mentioned in my original question.
Related
Im new in MVC pattern but im involved in a project which i am asked to implement repository pattern and unit of work,tons of examples online with 100 different implementations thats also a pain,because there is no clear way,any way,here is what i am doing and i would like you to give me a reason why should i use this damn pattern:
i have many controllers i instantiate the the model,and use it in my controller:
public CentralEntities DB = new CentralEntities();
i use it in my controller for example like this:
var turbineid = (from s in DB.MasterDatas
where s.name == turbinename
select new TrBineId
{
turbineID = s.m_turbine_id
}).Single();
TrBineId is my viewModel,any way the number of controllers are increasing and also in each controller i have many different LINQ,should i start with generic repository?
The damn reason to use repository pattern lies in implementing your solution with a clear separation of concerns and leverage domain I/O in a way that can be reused across your codebase.
You should start to revisit OOP and you'll need to double-check repository pattern.
At the end of the day, the need for certain patterns is already there, but it'll arise in your mind once you put the pieces in order.
I would start following some tutorial around the net about repository pattern to implement a proof-of-concept project and realize how it works.
Finally, Inversion of Control and Dependency Injection are concepts you'll need to manage to integrate your repositories and other patterns in your project to increase code composability and testability.
DISCLAMER: The following links are from my website about software architecture. You might want to check them as a possible reference implementation of repository pattern:
Repository
Agnostic repository
The repository pattern allows you to use the concept of Single responsibility principle, which mean (as an overview) one class = one role.
Your controler class is here for managing the request (Get, Post) and send back a response (FileResult, ActionResult...).
For the Data access (DAL, DAO) you will usually create a class per model entity (ClientRepository, CommandRepository), and you will create your methods for getting them (GetClients(), GetOneClientById(int id)...) within this class.
Edit for clarification after MatÃas comment:
This class will be called in your controller through his interface that you will also implement (with IOC or not).
You will then create a class instance of ClientRepository in your controller, but assigned to a reference of the interface type (IClientRepository).
**End Edit **
So we can imagin for Client Entity:
ClientController(All route for clients data)
IClientRepository (interface)
ClientRepository (Class which implement IClientRepository )
Then, in your controller you will call the repository like
IClientRepository clientRepo = new ClientRepository();
And then use the methods:
ICollection<Client> clients = clientRepo.YourMethod(int param1);
Advantages:
First of all, your code will be more clear and maintainable. Your DAO (DAL in .net) will keep the data access layer and you could use the GetAllClients method many time and you will not repeat yourself (DRY).
You can also apply easily some param on the method (like order, limit for pagination etc...)
It will be testable as well, I don't think that calling database in the controller can give you reasonable unit test results. You will also catch excption with a more "elegant way".
Small tip : When you will have more experience in the repo pattern, you could have a look at the Inversion of Control pattern
Working on an MVVM application. Each ViewModel class has a constructor which accepts a Repository class so that it can be mocked out for unit testing.
The application is designed to be operated across several windows at once. So it contains a number "View" or "Open" style methods which create new ViewModels and place them into new windows. Because these are triggered via the UI, they are often inside existing ViewModels. For instance:
public void ViewQuote(Quote quote)
{
if (quote.CreatedOn == null)
{
quote.CreatedOn = DateTime.Now;
}
NavigationHelper.NewWindow(this, new QuoteViewModel(quote, new Repository()));
}
Now, that flow control statement looks worth testing to ensure that quotes passed with a null CreatedOn date get assigned one. However, my test for this fails because although the parent ViewModel has a mocked Repository, the NewWindow method spins up a new ViewModel with a real-life Repository inside it. This then throws an error when it's used inside the constructor of that class.
There are two obvious options.
One is to pull out the date assignment into a stand-alone function to test. That'll work, but it seems too simplistic for its own function. Plus if I do it all over the application it risks creating too much fragmentation for easy readability.
The other is to somehow change the constructor code for ViewModels to not use the Repository directly. That might be an option here, but it's unlikely to be workable for every possible scenario.
Or is there a third way to design this better so I can pass a mocked Repository into the constructor of my new ViewModel?
Newing up services (or service-like objects such as repositories) is a design smell. And the problems that you're experiencing are the consequence.
In other words, you are lacking a clear and well-defined Composition Root.
Solution: Use proper dependency injection
The only clean solution to this is to inject services through the constructor. Repositories usually have a shorter lifecycle than the application itself, so in this case you would inject a factory that is able to create the repository.
Note that clear dependency trees are good design, but using a DI framework such as Autofac is only one technical solution to implement such a design. You can completely solve your problems and create a clean composition root without using a DI framework.
So although this is probably a lot of work, you should redesign your application to have a clear composition root. Otherwise, you will run into small issues over and over again, especially in the testing area.
You could work around it by adding a public Repository NewRepository property, in your ViewQuote method change it to look like this:
public void ViewQuote(Quote quote)
{
if (quote.CreatedOn == null)
{
quote.CreatedOn = DateTime.Now;
}
if(NewRepository == null) NewRepository = new Respository();
NavigationHelper.NewWindow(this, new QuoteViewModel(quote, NewRepository));
}
Then in your mock, just ensure that the public NewRepository property is assigned to before the test is run on that bit of code.
Not very elegant, but it would require the least amount of changing in my opinion.
I am looking to offload some controller functions in my MVC 5 project to a single function. Both views being passed in inherit from the base view.
CompetitionsViewModel:CompRegisterViewModel
So far, this appears to work:
private async Task<bool> RegisterUser(RegisterViewModel model, string returnUrl = "")
{...}
Calling code:
bool passed = await RegisterUser(model);
A few questions on this, though:
Is this the proper method of going about this when one of the controllers uses a view that is inherited from another view, and you want a separated function for this?
Is there anything I should be concerned about using async in this function? - Will model errors (ModelState.AddModelError) work as expected within this function? Everything appears to work on the surface, but I do have a ton of custom JQuery handling extensive error correction prior to this point.
Even though this is an async process, will the model still be passed as ref (less of a concern right now, but just for future knowledge).
Basically what is happening here is I have a cart that has the ability to register. You could also register independently from the cart, so I use a shared view for registration. As such, both parent views implement the child views, so inheritance of the view model seemed like the most intelligent route.
The options I see on the table are: recreate the process in both controller functions (duplicated code? ..maintenance nightmare), create an interface (having to update in multiple places when adding a field/changing a field?), or do what I did - one single function that handles both, while the calling methods handle their non-inherited functionality.
Do you see a fourth, better option, or does my solution seem acceptable?
The answer to this question is as follows:
Still unsure about best practice, but it does work fine.
as for whether this is considered good practice or not, I would find it very bad practice to duplicate code, so take it for what it is.
It works fine - AddModelError, etc. works.
Objects are passed by reference in normal circumstances, so I'm assuming "yes" for now. Will update if I run into a problem.
I wanna test the controller action, but one point is not coveraged by visual studio Code coverage tool.
public ActionResult Activate(int? id)
{
if (id == null)
return View("PageNotFound");
var city = repository.GetCityById(id.Value);
if (city == null)
return View("PageNotFound");
city.IsActive = !city.IsActive;
if (TryUpdateModel(city))
{
repository.Save();
return RedirectToAction("MyCities");
}
***return View("PageNotFound");***
}
in the code coverage, *return View("PageNotFound");* is not coveraged.
Because, I can not simulate the TryUpdateModel false stuation. TryUpdateModel can get false if model can not updated. Can u help about this?
TryUpdateModel will return false if the model validation fails.
(in which case you should not be showing a not found page)
In situations like these there are all kinds of options for you. One of them is creating a stub that overrides the actual functionality of the method you want to control.
For example, you can declare TryUpdateModel as virtual. In your unit test, instead of working with the original class, you inherit it and override the TryGetModel to simply return false. All other functionality is retained as is.
Now you call the Activate method on the derived class that has the exact same functionality apart from the simulated TryUpdateModel method, allowing you to test the desired use case without breaking your head as how to simulate a certain execution path.
This technique is not without drawbacks: it makes you declare the method as virtual only for testing purposes, thus preventing you from making it sealed, or static. There are other, more advanced techniques (Mock objects, isolation frameworks) but I think that this is a good enough solution for this scenario.
You don't include code to show how the lifetime of the cargo dependency is handled, so I'm only guessing, but...
It should be possible to pass a mock or fake instance of this class to the controller as part of your test setup (if it isn't currently possible, refactor until it is).
With the mock in place you can isolate and test the behaviour as you want.
Aside: I disagree with the comment from #dreza... testing this sort of business logic is very important.
I would also caution against faking the implementation of TryUpdateModel as suggested by #Vitaliy, after all you want to test what happens if the cargo model is invalid (not just pretend that it is by providing a new version of core code).
OK,
I solved solution. I deleted the TryUpdatemodel if condition. Directly used repository.Save() method. Because I did not send parameter a model to activate method.
I've been going through the process of cleaning up our controller code to make each action as testable. Generally speaking, this hasn't been too difficult--where we have opportunity to use a fixed object, like say FormsAuthentication, we generally introduce some form of wrapper as appropriate and be on our merry way.
For reasons not particularly germaine to this conversation, when it came to dealing with usage of HttpContext, we decided to use the newly created HttpContextWrapper class rather than inventing something homegrown. One thing we did introduce was the ability to swap in a HttpContextWrapper (like say, for unit testing). This was wholly inspired by the way Oren Eini handles unit testing with DateTimes (see article, a pattern we also use)
public static class FooHttpContext
{
public static Func<HttpContextWrapper> Current = ()
=> new HttpContextWrapper(HttpContext.Current);
public static void Reset()
{
Current = () => new HttpContextWrapper(HttpContext.Current);
}
}
Nothing particularly fancy. And it works just fine in our controller code. The kicker came when we go to write unit tests. We're using Moq as our mocking framework, but alas
var context = new Mock<HttpContextWrapper>()
breaks since HttpContextWrapper doesn't have a parameterless ctor. And what does it take as a ctor parameter? A HttpContext object. So I find myself in a catch 22.
I'm using the prescribed way to decouple HttpContext--but I can't mock a value in because the original HttpContext object was sealed and therefore difficult to test. I can map HttpContextBase, which both derive from--but that doesn't really get me what I'm after. Am I just missing the point somewhere with regard to HttpContextWrapper?
Edit to clarify intent
We found ways to solve the problem--but I guess the ultimate question we're walking away with is what value HttpContextWrapper brings to the table? I don't doubt somewhere someone totally had an a-ha! moment with it, but it just doesn't come to me. Most postings I see here discuss it in terms of testability--but my own experience has led me to believe that it didn't bring much in that context. Unless we're doing it wrong. (Wholly possible).
This blog post explains it pretty well:
http://splinter.com.au/httpcontext-vs-httpcontextbase-vs-httpcontext
The point is that 'vintage' HttpContext does not implement HttpContextBase, and isn't virtual, and therefore cannot be Mocked. HttpContextBase was introduced in 3.5 as a mockable alternative. But there's still the problem that vintage HttpContext doesn't implement HttpContextBase.
So HttpContextWrapper is a handy wrapper class (or 'kludge') that does implement HttpContextBase, and can be used when injecting a 'real' HttpContext using IOC, usually with a factory method like this: () => new HttpContextWrapper(HttpContext.Current)
You should be using the abstract HttpContextBase which is much easier to mock instead of HttpContextWrapper.
public static Func<HttpContextBase> Current =
() => new HttpContextWrapper(HttpContext.Current);
And in your unit test:
SomeClass.Current = MockHttpContextBase(); // Sorry I don't know the syntax for Moq
One real world example other than testing.
Besides mocking I stumbled upon a peculiar issue that the wrapper class really helped me solve. We have an application in Azure and we have control only on the application. It sits behind a reverse proxy which changes the host header of the incoming requests and sends the original host in a custom header. The application relies on the host header in order to build dynamic links, validate redirects etc. so we needed a way to substitute the host that was set in the HttpContext.HttpRequests.Url property. Since we exposed the HttpContext only as HttpContextBaase using the wrapper everywhere in the app we were able to create a class that inherits HttpContextWrapper and overrides the Request and then returns object that inherits from the RequestWrapper and overrides the Url property. So in the end the application replaced the host in the url that ASP.NET used for the context with the custom host from the custom header the reverse proxy has set. There was no other way from within the app to do that other than manually searching through the code where HttpContext.Request.Url is used and applying fix.