我想测试我的Class,它调用第三方Web服务。是否可以使用FakeItEasy?
Wenn我尝试从Reference.cs
(自动生成)伪造班级,UnitTest开始并且没有回来。
Reference.cs (自动生成)
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class ws_AccessoryClient : System.ServiceModel.ClientBase<AccessoryService.ws_Accessory>,
AccessoryService.ws_Accessory
{
public ws_AccessoryClient()
{
}
public ws_AccessoryClient(string endpointConfigurationName) :
base(endpointConfigurationName)
{
}
public AccessoryService.ResponseMessageOf_ListOf_SomeMethodInfo SomeMethod(
AccessoryService.RequestMessageOf_SomeMethod request)
{
return base.Channel.SomeMethod(request);
}
}
test.cs中
[Test]
public void DoBusinessLogicTryTest()
{
var accessoryProxy = A.Fake<ws_AccessoryClient>();
}
答案 0 :(得分:3)
正如已经提到的,你可能不想做你单位测试的目的,因为这会导致比使用模拟接口的单元测试所需的更多噪声。但是,它是一种有效的集成测试方法,这将允许您测试您的WCF接线是否按预期工作。如果您采用更加行为驱动的测试方式,并且尽可能少地进行模拟,它还允许您测试整个应用程序。
我自己使用这种方法来使用我的博客NSubstitute中涵盖的Hosting a Mock as a WCF service来伪装假终结点。您需要做的主要事情是启动ServiceHost,为其指定要使用的端点地址,将上下文模式设置为单一,并提供要用作端点的模拟。
var serviceHost = new ServiceHost(mock, new[] { baseAddress });
serviceHost.Description.Behaviors
.Find<ServiceDebugBehavior>().IncludeExceptionDetailInFaults = true;
serviceHost.Description.Behaviors
.Find<ServiceBehaviorAttribute>().InstanceContextMode = InstanceContextMode.Single;
serviceHost.AddServiceEndpoint(typeof(TMock), new BasicHttpBinding(), endpointAddress);
我在测试中做的一件事是随机选择我托管端点的端口,并在测试期间将地址注入我的应用程序。这样,您的测试将能够在其他计算机上运行并构建服务器,而不会与正在使用的其他端口发生冲突。
查看您的示例后,您可能需要考虑使用WCF ChannelFactory来创建客户端,而不是使用具体的代理客户端类。 ChannelFactory使用您提供的接口动态创建代理,并允许您使用服务接口将代理注入其依赖项。这将使单元测试更容易,并为您提供更加分离的设计。
答案 1 :(得分:2)
你不能(为什么你想要?)。
如果要验证您所测试的类是否对该服务进行了调用,请将该服务调用包装在一个只调用该服务的类中,并使用接口对其进行定义。
interface ICallTheService
{
void CallTheService();
}
class ServiceCaller : ICallTheService
{
void CallTheService()
{
// Call the service...
}
}
然后你可以伪造这个类并验证你的测试类是否调用了 CallTheService 操作。
// fake the service caller and pass it into your service
var serviceCaller = A.Fake<ICallTheService>();
// Verify invocation
A.CallTo(() => serviceCaller.CallTheService()).MustHaveHappened();
我想测试我班级中的逻辑,取决于来自的响应 WCF-服务
这就是我认为你担心分离问题的地方。您的测试称为 DoBusinessLogicTryTest ,但它依赖于System.ServiceModel,这是一个基础架构问题。没有这种依赖性,您的业务逻辑应该是可测试的。如果您所测试的课程需要根据响应采取不同的行为,您可以执行以下操作:
interface ICallTheService
{
ServiceResponseModel CallTheService();
}
enum ServiceResponseModel
{
Success,
PartialSuccess,
FailureCondition1,
FailureCondition2,
// etc...
}
然后,您可以填写ICallTheService假的,以返回每个可能的响应,并根据此测试您的类。
A.CallTo(() => serviceCaller.CallTheService()).Returns(ServiceResponseModel.Success);
例如,如果某些异常(在WCF中定义)处理正确
这也与业务逻辑无关。实际处理异常是ICallTheService实现的责任。实际上,我会为此介绍另一个类,它的工作是将various possible exceptions从System.ServiceModel转换为响应模型。例如
class WCFErrorResponseTranslator
{
ServiceResponseModel TranslateWCFException (Exception ex)
{
if (ex.GetType() == typeOf(TimeoutException)) { return ServiceResponseModel.TimeOut; }
/// etc
}
}
然后可以单独测试此行为。