2

TL;DR: 在 MVVM 客户端中实现 ViewModel 和 WCF 服务之间的依赖关系的良好且可测试的方法是什么?

请阅读问题的其余部分,以获取有关我在尝试执行此操作时遇到的问题的更多详细信息:


我正在开发一个连接到 wcf 服务的 silverlight 客户端,我想为客户端编写单元测试。因此,我正在寻找在我的 ViewModel 中使用 wcf 客户端并测试该交互的良好解决方案。到目前为止,我已经找到了两种解决方案:

解决方案1:这实际上是我到目前为止的实现方式:

public class ViewModelExample
{
    public ViewModelExample(IServiceClient client)
    {    
            client.DoWorkCompleted += .. 
            client.DoWorkAsync();
    }
}

//This is how the interface looks like
public interface IServiceClient
{
    event EventHandler<AsyncCompletedEventArgs> DoWorkCompleted;
    void DoWorkAsync();
}

//I was able to put the interface on the generated clients because they are partial classes, like this:
public partial class GeneratedServiceClient : IServiceClient
{

}

好的部分:它相对容易模拟

不好的部分: 我的服务客户端和我的 ViewModel 一样长,当我有并发请求时,我不知道哪个答案属于哪个请求。

解决方案 2:受此答案 WCF Service Client Lifetime的启发。

public class ViewModelExample
{
    public ViewModelExample(IServiceFactory factory)
    {
        var client = factory.CreateClient();
        client.DoWorkCompleted += ...
        client.DoWorkAsync();
    }
}

好的部分:每个请求都在不同的客户端上,因此将请求与答案匹配不会再有问题。

不好的部分:测试更难。我每次都必须为工厂和 wcf 客户端编写模拟。这不是我想做的事情,因为我已经有 200 次测试...... :(

所以我的问题是,你们是怎么做到的?您的 ViewModel 如何与 wcf 服务通信,在哪里注入依赖项,以及如何测试该交互?我觉得我错过了什么。。

4

3 回答 3

1

尝试Func<IServiceClient>注入您的虚拟机而不是客户端实例;您将注入一个“语言级工厂”,而不是为此构建一个类。在工厂方法中,您可以根据需要实例化您的客户端(例如,每次访问都可以为此创建一个新实例)。

不利的一面是,您仍然必须在大多数情况下接触您的测试,但我认为它的工作量会减少:

public ViewModelExample(Func<IServiceClient> factoryMethod)
{
    var client = factoryMethod();
    client.DoWorkCompleted += ...
    client.DoWorkAsync();
}
于 2012-06-20T13:01:34.703 回答
0

WCF 服务应该有自己的测试来确认自身的功能。

然后,您应该模拟此 WCF 服务并在您的使用者中编写单元测试。

不幸的是,这是一种痛苦,我们都必须做的事情。务实并完成它,它将避免您将来被咬。

于 2012-06-20T12:51:34.650 回答
0

您是否偶然使用了 IoC 容器?如果你有,这个问题将被容器完全缓解(你只需注册IService依赖项,以便在每个请求时创建为全新的)。

如果不是这样,那么

我每次都必须为工厂和 wcf 客户端编写模拟

是你如何处理这种“问题”。成本相对较小,每次测试可能需要 2-3 行额外的代码(您所要做的就是设置工厂模拟以返回服务模拟,无论哪种方式都需要)。

于 2012-06-20T13:01:30.507 回答