使用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);
}

这是由一个类实现的,该类使用实际生成的服务客户端代理进行调用。

我的问题是:我如何进行单元测试,让我的视图模型调用服务并用返回的数据填充我的集合?

使用WCF服务调用测试视图模型

扩展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;
}

任务对很多事情都有好处!