2

我在这里看到了几个处理类似问题的问题,但没有一个对我有帮助。

我在 MVC 3 项目中使用 NUnit 和 VS 2010。我有一个测试项目,正在编写我的第一个测试 Evar!:-)

你不为我终于得到它而感到自豪吗?!

这是我得到的错误

Microsoft.Practices.ServiceLocation.ActivationException:尝试获取数据库类型的实例时发生激活错误,键“MyConnection”----> Microsoft.Practices.Unity.ResolutionFailedException:依赖项解析失败,类型=“Microsoft.Practices。 EnterpriseLibrary.Data.Database”,名称 = “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 一起使用。

有什么好主意吗?:-) 谢谢大家!

4

2 回答 2

4

同意@Jesse 关于模拟依赖项。如果您不隔离 sut 那么它不是单元测试。(推荐阅读单元测试艺术

因此,从那开始,您可以说您正在编写集成测试。

如果不查看您的确切设置,很难说出问题所在。你提到的一件事是你已经“配置了你的web.config”。

但是您是否在测试项目中设置了配置文件?配置将从您的单元测试项目加载,而不是 MVC 项目。

于 2012-06-07T00:49:25.697 回答
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 时,您的测试模拟就会启动并返回您的预期数据。

于 2012-06-06T23:01:00.357 回答