RhinoMocks 测试回调方法
我有一个服务代理类,它对服务操作进行异步调用。我使用回调方法将结果传递回我的视图模型。
在对视图模型进行功能测试时,我可以模拟服务代理以确保在代理上调用方法,但如何确保回调方法也被调用?
使用RhinoMocks,我可以测试事件是否被处理以及模拟对象上的事件引发事件,但如何测试回调?
ViewModel:
public class MyViewModel
{
public void GetDataAsync()
{
// Use DI framework to get the object
IMyServiceClient myServiceClient = IoC.Resolve<IMyServiceClient>();
myServiceClient.GetData(GetDataAsyncCallback);
}
private void GetDataAsyncCallback(Entity entity, ServiceError error)
{
// do something here...
}
}
ServiceProxy:
public class MyService : ClientBase<IMyService>, IMyServiceClient
{
// Constructor
public NertiAdminServiceClient(string endpointConfigurationName, string remoteAddress)
:
base(endpointConfigurationName, remoteAddress)
{
}
// IMyServiceClient member.
public void GetData(Action<Entity, ServiceError> callback)
{
Channel.BeginGetData(EndGetData, callback);
}
private void EndGetData(IAsyncResult result)
{
Action<Entity, ServiceError> callback =
result.AsyncState as Action<Entity, ServiceError>;
ServiceError error;
Entity results = Channel.EndGetData(out error, result);
if (callback != null)
callback(results, error);
}
}
谢谢
I have a service proxy class that makes asyn call to service operation. I use a callback method to pass results back to my view model.
Doing functional testing of view model, I can mock service proxy to ensure methods are called on the proxy, but how can I ensure that callback method is called as well?
With RhinoMocks I can test that events are handled and event raise events on the mocked object, but how can I test callbacks?
ViewModel:
public class MyViewModel
{
public void GetDataAsync()
{
// Use DI framework to get the object
IMyServiceClient myServiceClient = IoC.Resolve<IMyServiceClient>();
myServiceClient.GetData(GetDataAsyncCallback);
}
private void GetDataAsyncCallback(Entity entity, ServiceError error)
{
// do something here...
}
}
ServiceProxy:
public class MyService : ClientBase<IMyService>, IMyServiceClient
{
// Constructor
public NertiAdminServiceClient(string endpointConfigurationName, string remoteAddress)
:
base(endpointConfigurationName, remoteAddress)
{
}
// IMyServiceClient member.
public void GetData(Action<Entity, ServiceError> callback)
{
Channel.BeginGetData(EndGetData, callback);
}
private void EndGetData(IAsyncResult result)
{
Action<Entity, ServiceError> callback =
result.AsyncState as Action<Entity, ServiceError>;
ServiceError error;
Entity results = Channel.EndGetData(out error, result);
if (callback != null)
callback(results, error);
}
}
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
玩了一下这个,我想我可能有你正在寻找的东西。首先,我将显示我用来验证这一点的 MSTest 代码:
您会注意到一些事情:
我将您的回调设置为内部。您需要使用InternalsVisisbleTo() 属性,以便您的ViewModel 程序集向您的单元测试公开内部结构(我对此并不着迷,但这种情况在极少数情况下会发生)。
每当调用 GetData 时,我都会使用 Rhino.Mocks“Do”来执行回调。它没有使用提供的回调,但这实际上更像是一个集成测试。我假设您已经进行了 ViewModel 单元测试,以确保在适当的时间执行传入 GetData 的实际回调。
显然,您需要创建模拟/存根实体和 ServiceError 对象,而不是像我一样只是新建。
Played around with this a bit and I think I may have what you're looking for. First, I'll display the MSTest code I did to verify this:
You'll notice a few things:
I made your callback internal. You'll need to use the InternalsVisisbleTo() attribute so your ViewModel assembly exposes internals to your unit tests (I'm not crazy about this, but it happens in rare cases like this).
I use Rhino.Mocks "Do" to execute the callback whenever the GetData is called. It's not using the callback supplied, but this is really more of an integration test. I assume you've got a ViewModel unit test to make sure that the real callback passed in to GetData is executed at the appropriate time.
Obviously, you'll want to create mock/stub Entity and ServiceError objects instead of just new'ing up like I did.