【问题标题】:Unit testing Silverlight mocking WCF client单元测试 Silverlight 模拟 WCF 客户端
【发布时间】:2011-06-15 14:27:01
【问题描述】:

我有 SL 代码

public void LoadData()
{
    MyClient myClient = new MyClient();
    myClient.MyMethodCompleted += new EventHandler<MyMethodCompletedEventArgs>(myMethod_MyMethodCompleted);
    myClient.MyMethodAsync();
}

然后完成的方法根据从服务器返回的内容设置属性。

工作正常,但我想对类进行单元测试,并且属性都是私有的。 我希望做一些类似的事情

public void LoadData(IMyClient myClient = null)
{
    if(myClient == null) {
        MyClient myClient = new MyClient();
    }
    ...

并传入一个mock,但是客户端的接口不包含异步方法,而只有原始的服务器端非异步方法 即 public ReturnType MyMethod();

所以我尝试使用 MyClient 作为 Mock 对象的基类

public MyMockClient : MyClient
new public ReturnType MyMethod() 
{
     ...

但是基础构造函数会导致各种问题,我不想在测试项目中添加另一个服务引用。

我错过了一个技巧,这可以在没有任何第三方模拟工具的情况下完成吗?

【问题讨论】:

    标签: silverlight wcf unit-testing mocking


    【解决方案1】:

    我建议您在类的构造函数中指定 MyClient 实例:

    public class MyClass
    {
        private MyClient _client;
    
        public MyClass()
            : this(new MyClient())
        { }
    
        public MyClass(MyClient client)
        {
            _client = client;
            _client.MyMethodCompleted += ...
        }
    
        public void LoadData
        {
            _client.MyMethodAsync();
        }
    }
    

    然后您可以子类化 MyClient(或者更好的是,重构它以实现一个接口)来实现您的模拟版本的客户端。

    回应cmets 为了在自动生成的 WCF 客户端类上实现接口,您可以使用Partial Classes。例如,假设您的自动生成的客户端在命名空间 MyNamespace 中被称为 MyClient,那么您的部分类需要如下所示:

    namespace MyNamespace
    {
        public partial class MyClient : IMyClientInterface
        {
    
        }
    }
    

    假设生成的MyClient 包含IMyClientInterface 上的所有成员,则不需要进一步的代码,您可以在IMyClientInterface 的实例上构建您的类

    【讨论】:

    • 除了我无法创建 MyClient 的新实例,因为 WCF 服务创建者已经创建了它,所以我已经处理它,需要一个端点地址并访问持有该类的项目中的服务引用正在测试中。我也不能让 MYClient 隐含一个接口,因为每次更新服务时,类都会自动重新生成。
    • @rob,如果自动生成给您带来问题,您可以使用部分类来实现接口。这对你有用吗?
    • @Steve Greatrex,部分类的想法非常有效,非常感谢。
    • @rob 没问题 - 你可能想把它标记为答案 ;)
    【解决方案2】:

    您可以创建您选择的接口,然后创建与 MyClient 对话的适配器包装器,如下所示:

    public interface IClient
    {
        void Foo();
        int Bar();
    }
    
    public class MyClientAdapter : IClient
    {
        private MyClient Client { get; set; }
    
        public MyClientAdapter(MyClient client)
        {
            Client = client
        }
        public void Foo()
        {
            Client.Foo();
        }
    
        public int Bar()
        {
            return Client.Bar();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-12-07
      • 1970-01-01
      • 1970-01-01
      • 2016-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-30
      相关资源
      最近更新 更多