使用WCF服务调用测试视图模型
本文关键字:视图 模型 测试 调用 WCF 服务 使用 | 更新日期: 2023-09-27 18:29:28
我想对进行wcf服务调用的视图模型进行单元测试。
我的视图模型:
public class FooViewModel : Screen
{
private IService service;
public FooViewModel(IService service)
{
this.service = service;
}
public void Load()
{
service.LoadThisAndThat((o,e) =>
{
//Fill collections and so on
});
}
}
我的服务客户端接口:
public interface IService
{
void LoadThisAndThat(EventHandler<ThisAndThatCompletedArgs> callback);
}
这是由一个类实现的,该类使用实际生成的服务客户端代理进行调用。
我的问题是:我如何进行单元测试,让我的视图模型调用服务并用返回的数据填充我的集合?
扩展Sheridan的答案-你想测试什么?
- 网络连接
- 服务框架(例如WCF)
- 线程的.NET实现
我猜您真正感兴趣的只是视图模型如何响应服务提供的数据。让我们稍微重新考虑一下您的代码,使其更加透明(我们所做的只是从服务方法的签名中删除EventHandler
委托):
public class FooViewModel : Screen
{
private IService service;
public FooViewModel(IService service)
{
this.service = service;
}
public void Load()
{
Task.Factory.StartNew(() => service.GetResult())
.ContinueWith(t =>
{
//Fill collections and so on
});
}
}
public interface IService
{
Result GetResult();
}
这能回答你的问题吗?不
即使您要模拟IService
的实现,线程的.NET实现也不能保证对service.GetResult()
的调用何时运行,或者结果何时返回到视图模型。但是,我们对测试.NET线程实现感兴趣吗?我想不会。
如果您致力于测试,那么您必须将测试视为代码的一流消费者。为此,我们必须修改我们的代码,使其更适合测试。下面取二:
public class FooViewModel : Screen
{
private IService service;
public FooViewModel(IService service)
{
this.service = service;
}
public void Load(bool runAync = true)
{
if (runAync)
Task.Factory.StartNew(() => service.GetResult())
.ContinueWith(t => SetResults(t.Result));
else SetResults(service.GetResult());
}
private void SetResults(Result result)
{
//Fill collections and so on
}
}
在这里,我们为Load()
方法引入了一个布尔参数,它将默认为true
。在测试过程中,我们用false
调用它,以确保同步处理结果,并且我们的视图模型在返回数据时的行为与我们预期的一样。
如果您不喜欢添加额外的参数,可以将SetResults
方法公开,并将其作为测试期间的初始化步骤。
得出的结论是,我们不应该害怕对公共实现进行更改以适应测试。
只需实现一个在TestService
类中返回一些数据的方法。其目的不是测试WCF服务是否工作,而是测试视图模型的工作方式。因此,我们创建了一个appears
的情况,就好像服务正在完美地工作。。。我们只需返回所需的数据,但不需要调用实际的服务,这是我们试图避免的主要事情之一。
这里的问题是回调是异步调用的。回调模式已过时,请使用Task!你可以做
public Task<int> Load()
{
TaskCompletionSource<int> source = new TaskCompletionSource<int>();
service.LoadThisAndThat((o,e) =>
{
//Fill collections and so on
source.SetResult(e.Count);
});
return source.Task;
}
以便在测试中可以(同步)进行
public void test()
{
var result=Load().Result;
}
任务对很多事情都有好处!