Mocking a Controller dependency with Moq using specflow - asp.net-mvc

I am new to specflow and a have a doubt about how to mock my
controller dependencies.
For instance I have a UserController class which depends on my
UserRepository class that a pass to the controller class on its
constructor.
So using Moq I am doing something like this:
var mock = new Mock<UserRepository>();
mock.Setup(m => m.ListAll()).Returns(new List<User>());
var browser = new IE(string.Format("http://localhost:4265/{0}",
username));
But my controller is not using the mocked object, how should I do
that?
Thanks

You are mixing three (atleast) test framework, which ofcourse is cool, but you should probably stop and consider what it is you want to test.
Watin is good for testing your UI as it controls a browser instance. I find it good at making regression tests http://en.wikipedia.org/wiki/Regression_testing
Specflow is great as well - personally i like to use it for closing the gap between business developers and (us) software developers as we can actually define requirements in terms we both understand (and probably other parts of the organization as well) I don't want to start a flame war, but it can introduce more problems than it solves, unless you focus on its real values. We use this at work by testing the service layer (one layer below the controllers in the presentation layer) and we actually only mock the database, external services and file system etc - which makes our specflow tests some kind of integration tests.
Moq is a mocking framework and can ofcourse be used in any kind of tests (like i just let it slip we do) but this is such a great tool for unit testing.
So to return to your question. If you want to make one test to find all your bugs, you're in trouble ;) I know you don't want that - that was just a silly suggestion i made - but really, if you just want to do integration tests (tests running from the UI down through several layers/dependencies) you could easily mix different testing frameworks like you are now, but then why mock the user repository? Is that because you don't want to hit the database?
Anyways one way to do the integration test you seem like you want would be to configure your solution to use a mock - or perhaps a stub would do (create a fake userrepository that returns the data you want to test with) - you should use a Dependency framework like Unity, Ninject or structure map (boy let's not start a war about what framework to use) and have the test url Watin is using launch your site using a configuration with the fake/mock repositories.
You could on the other hand do unit testing on your controllers, services etc. You might even want to try out TDD but that's a whole other chapter i can't cover here!

You are not doing anything with the mock to inject it into your controller. Your controller needs to be given the user repository in order for it to be used.
Also you need to accept more answers.

Related

What are the next steps for unit testing with dependency injection?

I'll start out by saying I'm a huge fan of unit testing. I've been using it for a couple of years. So far, though, my use has been limited to ensuring engineering calculations are performed correctly, strings are formatted properly, etc. Basically, testing my work on class libraries to be consumed in other projects.
Now, I want to branch out and apply unit testing to my work on ASP.NET Web API. At this point I have my controller written and working with Ninject. Although I'm using Ninject, I'm still not 100% sure why I'm doing it and haven't seen the benefits yet.
On to my question, what are the next steps for unit testing my Web API controllers? What should I do next and when will I reap the benefit of using Ninject?
Next, you could create fake data (or a mock) that your controller can return to your views. This will allow you to do front end development without having to complete the back end implementation.
The benefit of using Ninject is that you can create mock objects for testing purposes. By injecting the interface instead of the concrete implementation you can easily switch between the real and mock object. To do this you simply change which one should be injected in the Ninject bindings. Using something like Rhino Mock in conjunction with Ninject you can write and test your code (controllers, views, etc) without having to fully implement all of the functionality. When you're ready to implement a mocked piece of functionality, you don't have to rewrite your code to accommodate the changes, you simply update your bindings. Now real data will display on your pages instead of the mocked data you created previously.

Understanding unit Testing in Grails

I'm a grails beginner. and was trying to understand the unit test ..
when i create a domain class Author grails automatically creates a test controller AuthorControllerTests for that domain.
so . in test controller the second line is #Mock(Author)
what does that mean.. what is the advantage i get when i mock a domain class?
as it says in the extensive documentation on testing:
The Mock annotation creates mock version of any collaborators. There is an in-memory implementation of GORM that will simulate most interactions with the GORM API. For those interactions that are not automatically mocked you can use the built in support for defining mocks and stubs programmatically.
Also AuthorControllerTests are the tests for the AuthorController, not the Author domain class.
Just to add something, mocking is useful when you need to isolate a "unit" of code like here your controller.
By isolating, we mean write simple components to replate and simulate all dependancies. This simple components are what we call Mocks.
Grails here gives you the possibility to mock the domain class which will make your tests easier as it won't store the information in the database.
If you want to test the whole stack, from the controller to the database, it's what we call an integration test.
hope it helps

A bit lost with organizing real world application code in asp.net mvc

I have the following real world scenario, somewhat simplified for the sake of this example
I have an object, let's call it Movie which will consist of several attributes, such as
release date
actors (array)
genre
rating
I need to be able to have a form where a new movie can be entered, with the following elements on the form:
date calendar
drop down list with actors
grop down list with genres
rating field with stars
What would be a clear consice way to organise my code using asp.net mvc, please outline where
data access logic goes
business logic goes (validation etc)
I would like to use ViewModel concept here
So far I have
Movie model
MovieViewModel view model
IMovieRepository interface
But I am unclear how does the actors/genres arrays fit into this and where do I fetch the data for it....does it go into IMovieRepository interface? Do I create another interface for it, in other words do I create an interface for a ViewModel? Do I create an interface for fetching genres too?
Another question:
How do I use ViewModels? Do I need to change anything in the application settings?
Controller action has something like View() in their body....how do I pass ViewModel there? Do I need to?
All in all, I just want a simple example of how you would implement the scenario above.
I am new to MVC and trying to make sure my code is organized well.
I remember very good word from Mike Cohn about Agile,"Best Practice Is Not Exist"
So you should always keep improving and refactoring not only for your code but also for your design, architecture, methodology, etc. and to do this You will need the following:
Put the maintainability as a none function requirement at the begging of all your work
BDD (Behavior Driven Development)
TDD (Test Driven Design)
TDD (Test Driven Development)
Unit Test with appropriate code coverage percentage
Automate your build deploy and test (Full automation of all repeated activities)
I know it a bit long introduction, but it necessary to understand me why I will advise you doing my approach as the following
My default approach in MVC project as the following
Flatten ViewModel that mapped using mapping layer by using
mapping library
Domain Model Consider DDD instructions
Service Layer that working with controllers as services
business logic
Repositories that used by the service layer and unit of work
But as I told you, Best Practice is Not Exist so I will start my development using BDD and TDD, and to implement this I founder and create a framework "DevMagicFake" that published on CodePlex, this framework will enable me to finish and complete my view and make it real working without any design or code for the underline layers at all
After the feature is working with all unit tests that cover most of it's behaviors, I will start refactoring the whole
ViewModel
Mapping
Service
Repository
etc.
and for each refactor I run all needed unit tests to find-out if my refactor break my code or breaking the accepted and knowing behaviors of the application, if it happen I will fix any break
So for example to save a Customer and retrieve it I will use only one line of code in each action method like the following
public ActionResult List(CustomerVeiwModel customerVeiwModel)
{
var repository = new FakeRepository<CustomerVeiwModel >();
repository.Save(customerVeiwModel);
And to retrieve the customer I just need to code the following:
var repository = new FakeRepository<CustomerVeiwModel>();
var customer = repository.GetById(1);
So I always take the decisions of the ViewModel, Repository, Architecture, etc, after 2 points
Feature completed and worked as the customer or the business expert
expected
I have unit tests that cover all the feature behaviors and response
This will make me aware of what to do about design, develop architecture and make me confidence that my code really work with high quality and as the customer expected
At the end, There is just one word, I always keep refactor and refactor, every new feature, modification, problem or issue happen to me it may lead to new architecture concept or design decisions that will change the whole application and I am always ready for them.
by the way you can download MVC3 project that use my approach form DevMagicFake on CodePlex, you will find project called "TryFakeMVC3"

What's the best practice to setup testing for ASP.Net MVC? What to use/process/etc?

i'm trying to learn how to properly setup testing for an ASP.Net MVC.
and from what i've been reading here and there thus far, the definition of legacy code kind of piques my interests, where it mentions that legacy codes are any codes without unit tests.
so i did my project in a hurry not having the time to properly setup unit tests for the app and i'm still learning how to properly do TDD and unit testing at the same time. then i came upon selenium IDE/RC and was using it to test on the browser end.
it was during that time too that i came upon the concept of integration testing, so from my understanding it seems that unit testing should be done to define the test and basic assumptions of each function, and if the function is dependent on something else, that something else needs to be mocked so that the tests is always singular and can be run fast.
Questions:
so am i right to say that the
project should have started with
unit test with proper mocks using
something like rhino mocks.
then anything else which requires
3rd party dll, database data access
etc to be done via integration
testing using selenium?
because i have a function which
calls a third party dll, i'm not
sure whether to write a unit test in
nunit to just instantiate the object
and pass it some dummy data which
breaks the mocking part to test it
or just cover that part in my
selenium integration testing when i
submit my forms and call the dll.
and for user acceptance tests, is it
safe to say we can just use selenium
again?
Am i missing something or is there a
better way/framework?
i'm trying to put in more tests for regression testing, and to ensure that nothing breaks when we put in new features. i also like the idea of TDD because it helps to better define the function, sort of like a meta documentation.
thanks!!
hope this question isn't too subjective because i need it for my case.
so am i right to say that the project should have started with unit
test with proper mocks using something
like rhino mocks.
The project should have started with a good separation of concerns. Once you have a good separation and you work with abstractions instead of concrete classes using a mocking framework and writing unit tests is a piece of cake.
then anything else which requires 3rd
party dll, database data access etc to
be done via integration testing using
selenium?
Yes.
because i have a function which calls
a third party dll, i'm not sure
whether to write a unit test in nunit
to just instantiate the object and
pass it some dummy data which breaks
the mocking part to test it or just
cover that part in my selenium
integration testing when i submit my
forms and call the dll.
You should not have a function that calls a third party DLL. You should write an abstraction/wrapper around this DLL which you would use and which will be mocked in the unit test where you will verify that your function calls the proper methods without really calling it. You would then use a DI framework in the application to do the plumbing.
and for user acceptance tests, is it
safe to say we can just use selenium
again?
Selenium or any other Web testing framework would be fine. In the more advanced ($) versions of Visual Studio you could write web tests.

Where to instantiate Data Context (adapter, connection, session, etc) in MVC?

We are building an ASP.NET MVC site, and I'm struggling with where to define a connection to best enable unit testing (I use 'connection' generically - it could be a session, a connection, an adapter, or any other type of data context that can manage transactions and database operations).
Let's say we have 3 classes:
UserController
UserService
UserRepository
In the past, we'd do something like this within a method of the UserService:
Using (ISomeSession session = new SomeSession())
{
session.StartTransaction();
IUserRepository rep = new UserRepository(session);
rep.DoSomething();
rep.Save();
session.Commit();
}
However, it wasn't really possible to unit test this since the dependency on SomeSession wasn't injected. However, if we use D.I. to inject the dependency in the UserService, the session hangs around for the life of the UserService. If there are multiple services called from the UserController, each could have sessions just hanging around until the UserController is garbage collected.
Any thoughts on how to better manage this? Am I missing something obvious?
Edit
Sorry if I wasn't clear - I understand that I can use Dependency Injection with the Session/Data Context, but then it's being maintained over the life of the Service class. For any longer-running actions/methods (i.e. let's say the service is being called by a batch process), this could lead to a lot of open sessions for no reason other than adding testability.
As RichardOD correctly observed, you can't use live database connections for writing unit tests. If you are doing it, then you are integration testing.
I have separate implementations for my repository interface, one real repository, and one fake repository for unit testing. The fake repository works on a generic list instead of a real data context. I am using DI (with Ninject to make things more comfortable, but you can do it just as well by hand) to inject the correct repository.
There are only very few instances in which I am unit testing with real connections, but that's a unit test for my repository class, not for any controller, UI or Business layer objects.
Edit: With the comment you added, I think I now understand what you were actually asking for. Funny you'd ask something about that, since I worked on the very same subject last week :-)
I instantiate the data context inside a very thin wrapper and put the context inside the HttpContext.Current.Items dictionary. This way, the context is global, but only for the current request.
Still, your question's subject is highly misleading. You were asking "where to instantiate a data context for unit testing" and the answer is that you usually don't. My unit tests still operate on fake repositories.
The easiest way is to have a Connectionstring that you define in web.config for development and production. For Unittests you define it in app.config of your Testproject.

Resources