我在这里看到几个问题,处理类似的问题,但没有一个问题对我有所帮助。
我在MVC 3项目中使用NUnit和VS 2010。 我有一个测试项目,正在编写我的第一个测试Evar! :-)
难道你不自豪我终于到了吗?!
这是我得到的错误
Microsoft.Practices.ServiceLocation.ActivationException:激活 尝试获取Database,key类型的实例时发生错误 “MyConnection”----> Microsoft.Practices.Unity.ResolutionFailedException:解析 依赖失败,输入= “Microsoft.Practices.EnterpriseLibrary.Data.Database”,name = “MyConnection的”。在解决时发生异常:例外情况是: InvalidOperationException - 无法构造数据库类型。 您必须配置容器以提供此值。
我已经将web.config
配置为所有这些并且数据在未在测试中运行时完美地返回,因此我知道它不是每个都死的配置,当与NUnit一起使用时它就会死亡。
这是我的连接信息:
<section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
...
<dataConfiguration defaultDatabase="MyConnection" />
<connectionStrings>
<add name="MyConnection" connectionString="Data Source=MyServerName;Initial Catalog=MyDB;user id=MyUser;password=MyPassword"
providerName="System.Data.SqlClient" />
</connectionStrings>
我已经使用NuGet安装了DaaB,并且还进行了干净的手动参考。无论哪种方式,数据在正常使用情况下都能正常加载,但在测试中它会在此行中死亡:
var database = DatabaseFactory.CreateDatabase("MyConnection");
在这个方法中
public IEnumerable<SchoolSearchResultsDTO> Find(SchoolSearchInputDTO dto) {
List<SchoolSearchResultsDTO> fullList;
var database = DatabaseFactory.CreateDatabase("MyConnection");
using (var command = database.GetStoredProcCommand("dbo.usp_School_SearchBySchoolName")) {
database.AddInParameter(command, "@I_strSchoolName", DbType.String, dto.SearchTerm);
database.AddInParameter(command, "@I_intNumberOfRecords", DbType.Int32, dto.MaxSearchResults);
using (var reader = database.ExecuteReader(command)) {
fullList = new List<SchoolSearchResultsDTO>();
while (reader.Read()) {
var fullRecord = new SchoolSearchResultsDTO();
fullRecord.SchoolID = reader.GetInteger("SchoolId");
fullRecord.SchoolName = reader.GetString("SchoolName");
fullRecord.IsDetailedDisplayMode = reader.GetBoolean("IsDetailedDisplayMode");
fullList.Add(fullRecord);
}
reader.Close();
}
}
return fullList;
}
所有其他帖子都谈论错误配置等。我很确定我配置正确,否则我不会在正常使用情况下获取数据。所以它与NUnit和DaaB在一起。
有什么好主意吗? :-) 谢谢大家!
答案 0 :(得分:4)
同意@Jesse关于模拟依赖关系。如果你没有隔离sut那么它不是单元测试。 (建议阅读Art of UnitTesting)
因此,你可以说你正在编写集成测试。
如果不仔细查看确切的设置,很难说出问题所在。你提到的一件事是你已经“配置了web.config
”。
但是你在测试项目中设置了一个配置文件吗?配置将从您的单元测试项目加载,而不是MVC项目。
答案 1 :(得分:2)
通常,最好避免在单元测试中直接命中数据库。我建议暂时留出一些关于创建有价值和可靠的单元测试的嘲笑。通过模拟,您可以向相关控制器注入一个模拟的服务层,该层将被设置为返回您期望的数据库数据。
在测试中,您将创建该服务层的模拟。有关使用moq(我的模拟框架首选项)的示例:
// create your expected data
var YourExpectedData = new IList<SchoolSearchResultsDTO>();
// .... add your expected information
//create & setup mock
var _service = new Mock<IYourService>();
_service.Setup(service => service.Find(It.IsAny<SchoolSearchInputDTO>())).Returns(YourExpectedData);
// create your controller
var controller = new YourCountroller(_service.object())
从这一点开始,你的单元测试非常简单。每当在各种代码中调用方法find时,您的测试模拟就会启动并返回您的预期数据。