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();
}
}
精彩评论