Best Practice For Mocking Repository Pattern
I'm starting out with IoC / Mocking and am looking to make sure I'm using 'best practice' for my repositories.
I'm setting up interfaces for my repositories. The concrete implementations will point to SQL, whilst testing will use Moq to generate "fakes". I no开发者_开发知识库tice that I'm using Moq's callback feature a lot. In this article, the author states.
since Moq provides functionality in both of these areas for most of what you would want to do, there isn’t really too many different points at which you would need these tools. In fact, if you think you need to use “Callback” you should probably look a little harder to see if Moq can do what you want to do automatically.
I've had a look and can't see any other way to implement what I need - namely a 'fake' repository. Can someone please advise if there's something that I'm missing here? Is there any way to achieve this without the callback?
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
// Arrange
var mock = ContactRepositoryFake();
// Act
mock.Object.AddContact(new Contact() { Name = "bill" });
mock.Object.AddContact(new Contact() { Name = "jane" });
// Assert
Assert.IsTrue(mock.Object.AllContacts.Count() == 2);
}
public Mock<IContactRepository> ContactRepositoryFake()
{
var _allContacts = new List<Contact>();
var mock = new Mock<IContactRepository>();
mock.Setup(x=>x.AddContact(It.IsAny<Contact>()))
.Callback((Contact c) =>
{
_allContacts.Add(c);
});
mock.Setup(x => x.AllContacts).Returns(_allContacts);
return mock;
}
}
public interface IContactRepository
{
void AddContact(Contact contact);
IEnumerable<Contact> AllContacts { get; }
}
public class Contact
{
public string Name { get; set; }
}
Thank you very much in advance! Any other advise welcome :-)
Z
I personally do not see an issue with the way you are doing this. What I see is that you want to Mock and not Stub you repository. Which means you want it to "record" and return data back during the test. In this case Callback
is useful and really the only way to do this.
As for the comment if you are dealing with Stubbing more than mocking then Callback
would be rarely be used. the article imo is a bit to general and doesn't fully see the power of the Callback
.
You could just setup the following:
mock.Setup(x => x.AllContacts).Returns(GetExpectedContactList());
and have a helper function which returns a List of Contacts:
private static List<Contact> GetExpectedContactList()
{
....
}
And have different Helper methods to return specific data scenarios.
精彩评论