gpt4 book ai didi

c# - 如何配置 Moq 以使用通用 action

转载 作者:太空宇宙 更新时间:2023-11-03 13:28:29 25 4
gpt4 key购买 nike

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

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


(编辑)为了完整起见,这里是解决问题的部分:

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 部分:

    using System;

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

代码第 2 部分:

/// <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 部分:

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 部分:

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 部分:

public static class MockExtensions
{
public static Mock<T> AsMock<T>(this T obj) where T : class
{
return Mock.Get(obj);
}
}

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

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

最佳答案

您省略了 Moq 设置代码,这使得这有点困难,但我相信它看起来像这样:

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

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

// 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)。

关于c# - 如何配置 Moq 以使用通用 action<T>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21481115/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com