我有一个facade类,它使用WCF客户端代理。为了防止使用IDispose的WCF代理客户端出现问题( WCF中的bug仍未被MS修复),我创建了一个通用代理服务来执行调用WCF服务的基本管道。
我想用Moq对外观进行单元测试,还有一个问题是如何使用Moq进入单元测试中的特定调用。单元测试希望验证对流程管理器的调用只执行了一次,但是代码没有在“Use”方法中流动.
为了完整性起见,(编辑)是修复该问题的部分:
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());
}发布于 2014-01-31 14:01:36
您忽略了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 )。
https://stackoverflow.com/questions/21481115
复制相似问题