首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何配置Moq以利用通用action<T>

如何配置Moq以利用通用action<T>
EN

Stack Overflow用户
提问于 2014-01-31 13:21:18
回答 1查看 453关注 0票数 2

我有一个facade类,它使用WCF客户端代理。为了防止使用IDispose的WCF代理客户端出现问题( WCF中的bug仍未被MS修复),我创建了一个通用代理服务来执行调用WCF服务的基本管道。

我想用Moq对外观进行单元测试,还有一个问题是如何使用Moq进入单元测试中的特定调用。单元测试希望验证对流程管理器的调用只执行了一次,但是代码没有在“Use”方法中流动.

为了完整性起见,(编辑)是修复该问题的部分:

代码语言:javascript
复制
public AuthenticationFacade CreateSut()
        {
            ProcessManager = new Mock<IProcessManager>().Object;
            SessionWrapper = new Mock<ISessionWrapper>().Object;

            AuthenticationClientProxy = new Mock<Action<IAuthentication>>().Object;

            var authenticationProxyServiceMock = new Mock<IProxyService<IAuthentication>>();

            Mock<IAuthentication> mockAuthentication = new Mock<IAuthentication>();
            authenticationProxyServiceMock.Setup(aps => aps.Use(It.IsAny<Action<IAuthentication>>()))
                          .Callback<Action<IAuthentication>>(ac => ac(mockAuthentication.Object));

            AuthenticationProxyService = authenticationProxyServiceMock.Object;

            return new AuthenticationFacade(ProcessManager, SessionWrapper, AuthenticationProxyService);
        }

(参考代码)

代码第1部分:

代码语言:javascript
复制
    using System;

    namespace Progis.Kim
    {
        public interface IProxyService<T>
        {
            void Use(Action<T> action);
        }
    }

代码第2部分:

代码语言:javascript
复制
/// <summary>
    /// Helper class to fix the WCF Client Proxy usage bug with IDispose.
    /// Check: http://benmccallum.wordpress.com/2011/08/27/wcf-web-service-wrapper-closing-disposing-and-aborting-best-practices/
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ProxyService<T> : IProxyService<T>
    {
        public void Use(Action<T> action)
        {
            <cut>....
        }
    }

代码第3部分:

代码语言:javascript
复制
public class AuthenticationFacade : IAuthenticationFacade
    {
        private readonly IProcessManager processManager;
        private readonly ISessionWrapper sessionWrapper;
        private readonly IProxyService<IAuthentication> authenticationProxyService;

        public AuthenticationFacade(
            IProcessManager processManager, 
            ISessionWrapper sessionWrapper, 
            IProxyService<IAuthentication> authenticationProxyService)
        {
            this.processManager = processManager;
            this.sessionWrapper = sessionWrapper;
            this.authenticationProxyService = authenticationProxyService;
        }

        public bool ValidateGebruiker(string gebruikernaam, string wachtwoord)
        {
            bool authenticated = false;


            authenticationProxyService.Use(client =>
            {
                var sessionId = processManager.GetSessionId();

                  authenticated = client.ValidateGebruiker(
                    sessionId,
                    gebruikernaam,
                    wachtwoord);
            });

            return authenticated;
        }

代码第4部分:

代码语言:javascript
复制
public class AuthenticationFacadeFixture
    {
        public IProcessManager ProcessManager { get; set; }

        public ISessionWrapper SessionWrapper { get; set; }

        public IProxyService<IAuthentication> AuthenticationProxyService { get; set; }

        public AuthenticationFacade CreateSut()
        {
            ProcessManager = new Mock<IProcessManager>().Object;
            SessionWrapper = new Mock<ISessionWrapper>().Object;
            AuthenticationProxyService = new Mock<IProxyService<IAuthentication>>().Object;

            return new AuthenticationFacade(ProcessManager, SessionWrapper, AuthenticationProxyService);
        }
    }

代码第5部分:

代码语言:javascript
复制
public static class MockExtensions
    {
        public static Mock<T> AsMock<T>(this T obj) where T : class
        {
            return Mock.Get(obj);
        }
    }

代码第6部分(单元测试):

代码语言:javascript
复制
[TestMethod]
        public void ValidateGebruiker_calls_processmanager_getsessionid_once()
        {
            // Arrange
            var fixture = new AuthenticationFacadeFixture();
            var sut = fixture.CreateSut();

            var validUserPass = CreateValidGebruikersnaamWachtwoord();

            // Act
            sut.ValidateGebruiker(validUserPass.Gebruikersnaam, validUserPass.Wachtwoord);

            // Assert
            fixture.ProcessManager.AsMock().Verify(pm => pm.GetSessionId(), Times.Once());
        }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-01-31 14:01:36

您忽略了Moq设置代码,这使得这有点困难,但我相信它看起来如下所示:

代码语言:javascript
复制
AuthenticationProxyService.Setup(a => a.Use(It.IsAny<Action<IAuthentication>>()));

如果是这样的话,您可以执行以下操作:

代码语言:javascript
复制
// Not sure if you have this mock already, this is the "client" variable
// in your Use method action
Mock<IAuthentication> mockAuthentication = mockRepository.Create<IAuthentication>();

AuthenticationProxyService.Setup(a => a.Use(It.IsAny<Action<IAuthentication>>()))
                          .Callback<Action<IAuthentication>>(a => a(mockAuthentication.Object));

Callback方法从安装程序( Action<IAuthentication>)接收参数(在本例中是ValidateGebruiker中的代码),并使用模拟的IAuthentication对象调用它(如果还没有,则需要对其进行Setup )。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21481115

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档