【问题标题】:Mocking generic WCF ClientChannelWrapper async calls模拟通用 WCF ClientChannelWrapper 异步调用
【发布时间】:2011-02-26 08:50:38
【问题描述】:

我最近开发了一个 Silverlight 应用程序,它使用 Mark J Millers ClientChannelWrapper<T> 与 WCF 服务层通信(有效地终止服务引用并包装 IClientChannelClientChannelFactory)。 界面如下:

public interface IClientChannelWrapper<T> where T : class
{
    IAsyncResult BeginInvoke(Func<T, IAsyncResult> function);
    void Dispose();
    void EndInvoke(Action<T> action);
    TResult EndInvoke<TResult>(Func<T, TResult> function);
}

Wrapper 基本上采用通用异步服务接口(可能由 slsvcutil 生成或在 WCF ServiceContract 之后手工制作)并包装调用以确保在发生通道故障时创建新通道。 典型用法如下所示:

 public WelcomeViewModel(IClientChannelWrapper<IMyWCFAsyncService> service)
    {
        this.service = service;
        this.synchronizationContext = SynchronizationContext.Current ?? new SynchronizationContext();
        this.isBusy = true;
        this.service.BeginInvoke(m => m.BeginGetCurrentUser(new AsyncCallback(EndGetCurrentUser), null));
    }

private void EndGetCurrentUser(IAsyncResult result)
    {
        string strResult = "";
        service.EndInvoke(m => strResult = m.EndGetCurrentUser(result));
        this.synchronizationContext.Send(
                    s =>
                    {
                        this.CurrentUserName = strResult;
                        this.isBusy = false;
                    }, null);
    }

一切正常,但现在我想对使用ClientChannelWrapper 的视图模型进行单元测试。 我已经使用 Moq 设置了一个简单的单元测试:

[TestMethod]
    public void WhenCreated_ThenRequestUserName()
    {
        var serviceMock = new Mock<IClientChannelWrapper<IMyWCFAsyncService>>();
        var requested = false;

        //the following throws an exception
        serviceMock.Setup(svc => svc.BeginInvoke(p => p.BeginGetCurrentUser(It.IsAny<AsyncCallback>(), null))).Callback(() => requested = true);


        var viewModel = new ViewModels.WelcomeViewModel(serviceMock.Object);
        Assert.IsTrue(requested);
    }

我得到一个 NotSupportedException:

不支持的表达式:p => p.BeginGetCurrentUser(IsAny(), null)。

我对 Moq 还很陌生,但我想 ClientChannelWrapper 使用通用服务接口存在一些问题。想把我的脑袋绕过去很长一段时间,也许有人有想法。谢谢。

【问题讨论】:

    标签: wcf unit-testing moq channelfactory


    【解决方案1】:

    很抱歉回答我自己的问题,但我终于明白了。 以下是详细信息:

    通常,解决方案就在我面前,因为它在 Mark J Millers 的 IClientChannelWrapper 的具体实现中。在那里,他提供了两个构造函数,一个接收 WCF 端点名称的字符串(我在生产代码中使用),第二个:

    public ClientChannelWrapper(T service)
        {
            m_Service = service;
        }
    

    事不宜迟,这是我的新测试代码:

    [TestMethod]
        public void WhenCreated_ThenRequestUserName()
        {
            var IMySvcMock = new Mock<IMyWCFAsyncService>();
            var serviceMock = new ClientChannelWrapper<IMyWCFAsyncService>(IMySvcMock.Object);
            var requested = false;
    
            IMySvcMock.Setup(svc => svc.BeginGetCurrentUser(It.IsAny<AsyncCallback>(), null)).Callback(() => requested = true);
            var viewModel = new ViewModels.WelcomeViewModel(serviceMock);
    
            Assert.IsTrue(requested);
        }
    

    所以我基本上忽略了 ChannelWrapper 的接口,并使用我的 WCF 服务接口的 Mock 对象创建它的新实例。然后我设置了对服务的调用,该服务将在我的视图模型的构造函数中使用,如上所示。现在一切都像魅力一样。我希望这对某人有用,因为我认为 ClientChannelWrapper 的想法非常适合 Silverlight WCF 通信。请随时对此解决方案发表评论!

    【讨论】:

    • 不要抱歉回答您的问题。在其他人提供可能的解决方案之前,您找到了适合您的问题的答案。为什么您不应该与面临相同/类似问题的其他人分享这个答案?
    猜你喜欢
    • 2014-03-04
    • 1970-01-01
    • 2013-12-18
    • 1970-01-01
    • 1970-01-01
    • 2012-10-03
    • 2015-10-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多