我完全理解了Repository模式设计的想法。但是为什么我们需要实现iDepository接口类呢?这有什么特别的用途? 存储库类本身在没有接口类的情况下工作。
我认为有人会回答我这是为了脱离业务逻辑和数据逻辑。 但即使没有接口类,是不是数据逻辑解耦数据逻辑?
答案 0 :(得分:2)
当您对业务层进行单元测试时,可以注入一个IRepository类的测试对象。这有以下好处:
通过构造函数注入进行单元测试时,注入测试的一种方法是双倍的。假设您的存储库具有以下方法:
void Add(Noun noun);
int NumberOfNouns();
这是您商务舱的代码:
public class BusinessClass {
private IRepository _repository;
public BusinessClass(IRepository repository) {
_repository = repository;
}
// optionally, you can make your default constructor create an instance
// of your default repository
public BusinessClass() {
_repository = new Repository();
}
// method which will be tested
public AddNoun(string noun) {
_repository.Add(new Noun(noun));
}
}
要测试AddNoun而不需要真正的存储库,您需要设置测试双精度。通常你会通过使用像Moq这样的模拟框架来做到这一点,但我会从头开始编写一个模拟类来说明这个概念。
public IRepository MockRepository : IRepository {
private List<Noun> nouns = new List<Noun>();
public void Add(Noun noun) {
nouns.Add(noun);
}
public int NumberOfNouns() {
return nouns.Count();
}
}
现在你的一个测试就是这个。
[Test]
public void AddingNounShouldIncreaseNounCountByOne() {
// Arrange
var mockRepository = new MockRepository();
var businessClassToTest = new BusinessClass(mockRepository);
// Act
businessClassToTest.Add("cat");
// Assert
Assert.AreEqual(1, mockRepository.NumberOfNouns(), "Number of nouns in repository should have increased after calling AddNoun");
}
这实现了您现在已经测试了BusinessClass.AddNoun方法的功能,而无需触及数据库。这意味着即使您的Repository层存在问题(例如连接字符串出现问题),您也可以确保您的Business层按预期工作。这包括上面的第1点。
对于上面的第2点,无论何时编写测试数据库的测试,都应确保在每次测试之前它处于已知状态。这通常涉及在每次测试开始时删除所有数据并重新添加测试数据。如果没有这样做,那么你就不能对表中的行数运行断言,因为你不确定它应该是什么。
删除和重新添加测试数据通常是通过运行SQL脚本来完成的,这些脚本很慢并且在数据库结构发生变化时容易受到破坏。因此,建议仅将数据库的使用限制在存储库本身的测试中,并在单元测试应用程序的其他方面时使用模拟的存储库。
至于抽象类的使用 - 是的,这将提供提供测试双精度的相同能力。我不确定你会选择将哪些代码放在抽象基础中,哪些代码具体实现。 This answer to an SO question对抽象类与相互作用进行了有趣的讨论。
答案 1 :(得分:1)
首先,您必须了解存储库模式是什么。它是一个抽象层,因此应用程序的其余部分不必关心数据来自何处。
.NET中的抽象通常由接口表示,因为没有逻辑(代码)可以附加到接口。
作为奖励,界面还可以让您更轻松地测试您的应用程序,因为您可以轻松mock界面(或创建stub)
该界面还允许您改进数据层。例如,您可以从为所有存储库类使用数据库开始。但是后来你想要在Web服务背后移动一些逻辑。然后,您只需要使用WCF存储库替换数据库存储库。您可能还发现存储库很慢并且想要在其中实现简单的内存缓存(通过使用memcache或其他东西)
答案 2 :(得分:0)
我找到了一个非常有用的msdn页面,展示了存储库和测试驱动开发的想法 。 http://blogs.msdn.com/b/adonet/archive/2009/12/17/walkthrough-test-driven-development-with-the-entity-framework-4-0.aspx