我目前正在构建一个使用WCF Web服务的.net Web应用程序,以允许Flex前端访问数据库。
我正在为Web服务设置一些单元/集成样式测试,并且正在尝试找出允许测试在单独的测试数据库中访问和修改数据的最佳方法。
目前,我的单元测试项目中的连接字符串指向我的测试数据库,我的Web服务项目中的连接字符串指向我的开发数据库。但是,当我使用Linq时,似乎当我从测试类调用Web服务方法时,它使用开发数据库连接字符串。
我已经研究过创建模拟对象或内存数据库,但我相信会出现同样的问题。
有没有办法让这个工作,或者是我对我想要的不正确的想法,在哪种情况下有更好的方法来设置它?我在项目中的时间还早,我不会对显着改变解决方案的体系结构产生负面影响。
答案 0 :(得分:5)
史蒂文的建议是取消测试的WCF管道。这肯定会起作用并测试很多业务逻辑,但我希望我的自动化集成测试也能测试WCF交互。
我已经在我的项目的自动化测试中成功实现了这一目标。
请注意,WCF客户端和WCF主机可以共享同一进程。在这种情况下,它仍然通过WCF框架进行调用,具有所有约束和复杂性。您的WCF服务将从测试项目的配置文件中获取连接字符串。
为了说明这一点,如果客户端和服务在同一个进程中,配置文件就像这样。
<configuration>
<connectionStrings>
<add name="ContractsManager"
providerName="System.Data.SqlClient"
connectionString="Data Source=localhost;Initial Catalog=ContractsManager_AutoTest;Integrated Security=True;Pooling=False;Asynchronous Processing=true;Application Name=CmAutoTests"
/>
</connectionStrings>
<system.serviceModel>
<client>
<endpoint
name="LoggingService"
address="net.tcp://localhost:9612/loggingService"
binding="netTcpBinding"
contract="ContractsManager.ILoginService" />
</client>
<services>
<service name="ContractsManager.LoginServiceImpl">
<endpoint
address="net.tcp://localhost:9612/loggingService"
binding="netTcpBinding"
contract="ContractsManager.ILoginService">
</endpoint>
</service>
</services>
</system.serviceModel>
</configuration>
这样,您的自动化测试将找到特定于WCF的错误(例如,抛出未由Fault Contract指定的异常)。 今天我被这个保存了下来:我的代码有一个错误,意味着通道没有正确关闭。由于达到了节流限制,我的测试仍然悬而未决。花了一些时间来弄清楚,但我很感谢这个bug没有找到它的生产方式。
您的测试套件应在运行第一个测试之前设置服务主机。 (我已经尝试过每次测试设置和拆除服务主机,但运行速度太慢了。)
祝你好运。答案 1 :(得分:1)
确保Web服务中的代码最小化,而不仅仅是对服务层的简单调用。当您这样做时,您可以跳过直接调用Web服务,并创建一个也调用您的服务层的集成测试套件。在这种情况下,您正在进行进程内呼叫,而不是通过网络进行呼叫。在这种情况下,确保访问正确的数据库要容易得多,并且可以使用将回滚的数据库事务轻松地包装这些调用。您当然希望将任何操作回滚到数据库,因为维护RTM tests非常困难。一种方法是在测试中使用TransactionScope。
祝你好运。答案 2 :(得分:0)
由于WCF Web服务类未绑定到ASP.Net基础结构(不必从Syste.Web.Services.WebService继承),因此您可以轻松地将对存储库或对象上下文的引用注入到服务。然后,您可以使用单元测试来测试Web服务本身的任何逻辑,这些单元测试将使用一些模拟内存存储库,因此可以非常快速地运行。另一方面,集成测试将使用一些真实数据库,您可以捕获与持久层相关的错误。所以我不同意Steven认为Web服务方法应该只是一行调用一些服务层,除非逻辑太重,值得拥有自己的类。