Reputation: 2218
Below is the piece of the code of my action :-
public ActionResult Edit(int id)
{
ProductViewModel viewmodel = GetProduct(id);
if (viewmodel != null)
{
....................
}
}
In above code the if condition is based on the viewmodel.Which is returning from the GetProduct() method.Where GetProduct() method is the private method of the controller.
And i want to mock the ProductViewModel in my unit test method with MOQ.Can anyone suggest me what is the best way to do that ?
Upvotes: 0
Views: 950
Reputation: 4037
Your controller is very strongly coupled with the business logic, in this case the GetProduct method. I would suggest to restructure your code to have an interface for your "Product" specific business logic. The product controller should depend on an abstraction i.e. the interface and not anything that is concrete.
Use any dependency injection framework like sring.net, MS unity etc to inject concrete implementations (dependencies) into your controller.
Now use MOQ to mock the business logic so that controller can be tested in isolation.
Lastly, this is just another wonderful example demonstrating how if it becomes difficult to unit test a particular code component, it more than often points towards a design flaw than a unit testing/mocking framework incapability.
Upvotes: 0
Reputation: 224
The correct approach is to test indirectly the GetProduct method. Based on the name you are getting info from some kind of storage and you can mock that storage and return an object which is mapped by GetProduct in the ViewModel you want. You shouldn't mock method of the same class you are testing.
Upvotes: 0
Reputation: 11783
Usually using the MVVM pattern will look like :
public class MainViewModel : MyViewModelBase
{
private readonly IDataService _dataService;
public MainViewModel(IDataService dataService)
{
_dataService = dataService;
// ...
}
//..
}
And you'll have a locator that looks like:
public class ViewModelLocator
{
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
if (ViewModelBase.IsInDesignModeStatic)
{
SimpleIoc.Default.Register<IDataService, Design.DesignDataService>();
}
else
{
SimpleIoc.Default.Register<IDataService, DataService>();
}
// Here you'll register your view models
SimpleIoc.Default.Register<MainViewModel>();
}
//..
}
So, mocking this is fairly easy, just use the DI to pass in whatever you want to pass, and hook your methods either to static data (usually done to have nice output in design mode), or dummy methods that will return whatever it is you need.
Upvotes: 0
Reputation: 179
Ideally your viewModel should only have public properties that your view will be bound to. So there should not be a scenario where you would need to mock the viewModel class. If it is possible to, mock the GetProduct method to return an instance of ProductViewModel where the public properties have already been set. That way your viewModel will return exactly the values you want it to return for your test case.
Upvotes: 3