开发者

Unit testing Silverlight mocking WCF client

I have SL code

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

then the completed method sets properties from what is returned from the server.

Works fine, but I want to unit test the class and the properties are all private. I expected to do something along 开发者_开发知识库the lines of

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

and pass in a mock, but the interface for the client does not contain the async methods but only the original server side non async methods i.e. public ReturnType MyMethod();

So I tried using MyClient as a base class of a Mock object

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

but the base constructor causes all sorts of problems and I do not want to add another service reference to the test project.

Am I missing a trick, can this be done without any third party mocking tools ?


I would suggest that you specify the MyClient instance in the constructor of your class:

public class MyClass
{
    private MyClient _client;

    public MyClass()
        : this(new MyClient())
    { }

    public MyClass(MyClient client)
    {
        _client = client;
        _client.MyMethodCompleted += ...
    }

    public void LoadData
    {
        _client.MyMethodAsync();
    }
}

Then you can either subclass MyClient (or better yet, refactor it to implement an interface) to implement your mock version of the client.

In response to comments In order to implement an interface on the auto-generated WCF client class, you can use Partial Classes. For example, assuming your auto-generated client is called MyClient in the namespace MyNamespace, your partial class would need to look like the below:

namespace MyNamespace
{
    public partial class MyClient : IMyClientInterface
    {

    }
}

Assuming that the generated MyClient contains all of the members on IMyClientInterface then no further code is needed and you can construct your class on an instance of IMyClientInterface


You can create an interface of your choosing and then create and adapter wrapper that talks to MyClient like so:

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();
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜