Reputation: 26091
I have ran across some references to using Moq for unit testing. But after looking moq's wiki examples I can't really see anything benefit over just creating a mock repository. Am i missing somethings. below is an example of a mock repository I have created. Can moq optimize this an any way?
namespace Models
{
public class MockImagesRepository : IImagesRepository
{
private readonly BlogContext _context;
private readonly List<ImageViewModel> _imageViewModels;
public MockImagesRepository()
{
_context = new BlogContext();
_imageViewModels = new List<ImageViewModel>();
for (var i = 0; i < 10; i++)
{
_imageViewModels.Add(new ImageViewModel
{
Id = i,
AlternateText = "AlternateText " + i,
Description = "Description " + i,
Name = "Name " + i,
});
}
for (var i = 10; i < 20; i++)
{
_imageViewModels.Add(new ImageViewModel
{
Id = i,
AlternateText = "AlternateText " + i,
Description = "Description " + i,
Name = "Name " + i,
});
}
for (var i = 20; i < 30; i++)
{
_imageViewModels.Add(new ImageViewModel
{
Id = i,
AlternateText = "AlternateText " + i,
Description = "Description " + i,
Name = "Name " + i,
});
}
}
public int GetCount()
{
return _imageViewModels.Count;
}
public IEnumerable<ImageViewModel> FindRange(string format, int i, int recordsCount)
{
return _imageViewModels.Skip(i).Take(recordsCount);
}
public void Add(Image image)
{
}
public IEnumerable<Image> GetImages()
{
var images = new List<Image>();
foreach (var imageViewModel in _imageViewModels)
{
images.Add(new Image(imageViewModel));
}
return images;
}
#region Implementation of IDisposable
public void Dispose()
{
_context.Dispose();
}
#endregion
}
}
Upvotes: 4
Views: 1875
Reputation: 5407
Using Moq, you will not need to create your mock objects manually. This alone should save you time.
Instead of manually creating those mock objects, you will setup Moq to tell it how to behave depending on what/how things are called.
Using this methodology you will be able to do the following things:
Setup various responses based on different inputs or supplying the same results regardless of input (using Setup)
Allow you to simplify your testing code by submitting catch all values for parameters (using It.IsAny<> or It.Is<>)
Verify the number of times a method has been called, or whether it has been called at all. (using Verify). This will allow you to test that certain dependencies have been called with the correct parameters a defined amount of times.
Setup or Verify that the code will throw a certain exception (using Throws)
When you master Moq, for moderately complex tests cases, you will see a gain in writing your test cases.
Of course you could do all those things manually, but writing these facilities in your mocks will be time consuming.
Upvotes: 5
Reputation: 13399
You'll end up maintaining two repositories, one real and one fake. To make it worse, your fake one cannot really fake everything, for example, relationship between two objects, unless you do lots of coding. Eventually it'll not be worth it if you have a bit more complex objects than your example.
More than that, when testing a class that has a dependency on your repository, the repository is not the focus of the test, so it's much easier to mock using some framework like MOQ or RhinoMock.
Upvotes: 0
Reputation: 11495
For certain scenarios, your approach may be the easiest. However, when the behavior of the object you are mocking is more complex or varied, often you end up with either:
Using a mocking library like Moq lets you define your behaviour very clearly, often inline with your tests, so the interaction is much clearer and more direct.
Upvotes: 3
Reputation: 1444
Moq will enable you to skip the repository you have made. But the main use of a Mock object is to isolate your unit tests.
Example: if you want to test how an object react with the some data. You can mock that data.
In your case you can do something like:
// Create the mock from your interface
var mock = new Mock<IImagesRepository>();
// Setup the mock so it will return what you want
mock.Setup(foo => foo.GetImages()).Returns(new ImageViewModel
{
Id = i,
AlternateText = "AlternateText " + i,
Description = "Description " + i,
Name = "Name " + i,
});
// Then you can use it
functionThatNeedAnImageViewModel(mock.Object.GetImages());
Take a look at this Moq QuickStart for more infos.
Upvotes: 0