我完全理解Repository模式的设计思想。但是为什么我们需要实现iDepository接口类呢?这是什么特殊用途?repository类本身在没有接口类的情况下工作。
我想有人会回答我,这是为了从业务逻辑和数据逻辑中解耦。但是,即使没有接口类,数据逻辑不是解耦了数据逻辑吗?
发布于 2013-08-05 05:03:23
这样,当您对业务层进行单元测试时,就可以注入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方法的功能,而无需接触数据库。这意味着,即使存储库层出现问题(比如连接字符串出现问题),您也可以确保业务层按预期工作。这涵盖了上面的第1点。
至于上面的第二点,每当你编写测试数据库的测试时,你应该在每次测试之前确保它处于一个已知的状态。这通常涉及在每次测试开始时删除所有数据,并重新添加测试数据。如果不这样做,那么您就不能对表中的行数运行断言,因为您不能确定这应该是什么。
删除和重新添加测试数据通常是通过运行SQL脚本来完成的,SQL脚本速度很慢,并且在数据库结构更改时容易受到破坏。因此,建议将数据库的使用限制为仅对存储库本身进行测试,并在对应用程序的其他方面进行单元测试时使用模拟存储库。
至于抽象类的使用-是的,这将提供相同的能力来提供测试替身。不过,我不确定您会选择将哪些代码放在抽象库中,以及哪些是具体的实现。This answer to an SO question有一个关于抽象类与接口的有趣讨论。
发布于 2013-08-05 13:44:44
首先,您必须了解什么是存储库模式。它是一个抽象层,因此应用程序的其余部分不必关心数据来自何处。
.NET中的抽象通常由接口表示,因为没有逻辑(代码)可以附加到接口。
另外,该接口还可以让您更轻松地测试应用程序,因为您可以轻松地mock该接口(或创建stub)
该接口还允许您发展数据层。例如,您可以从为所有存储库类使用数据库开始。但是稍后,您需要将一些逻辑转移到web服务后面。然后,您只需将DB存储库替换为WCF存储库。您可能还会发现存储库速度很慢,并希望在其中实现一个简单的内存缓存(通过使用memcache或其他方法)
发布于 2013-11-12 20:04:22
我发现了一个非常有用的msdn页面,它演示了存储库和测试驱动开发的思想。http://blogs.msdn.com/b/adonet/archive/2009/12/17/walkthrough-test-driven-development-with-the-entity-framework-4-0.aspx
https://stackoverflow.com/questions/18043062
复制相似问题