如何模拟包括使用块的方法
本文关键字:方法 包括使 何模拟 模拟 | 更新日期: 2023-09-27 18:34:32
我是模拟单元测试的新手。
我有这种方法:
virtual public bool Authenticate(
Identity identity,
out IdentityReference entityReference,
out RightAssignment rights)
{
entityReference = null;
rights = null;
string passwordHash = identity.Passwd;
string customerId;
string userId;
using (IScope scope = DataAccess.GetScope())
{
DA.eCheckResult result = DataAccess.Check(
scope,
identity.Domain,
identity.Login,
passwordHash,
identity.BranchIdentification,
identity.CustomerIdentification,
out customerId,
out userId);
if (result == eCheckResult.cOK)
{
entityReference = new IdentityReference
{
CustomerId = customerId,
UserId = userId
};
rights = DataAccess.GetRightAssignment(scope, userId);
}
return DA.eCheckResult.cOK == result;
}
}
数据访问是一个声明如下的接口:
public interface IAuthenticateDA : IDisposable
{
eCheckResult Check(
IScope scope,
string domain,
string login,
string passwordHash,
string branchIdentification,
string customerIdentification,
out string customerId,
out string userId);
RightAssignment GetRightAssignment(IScope scope, string userId);
/// <summary>
/// Gets the scope of the underlying data accessor
/// </summary>
IScope GetScope();
}
我目前的嘲笑尝试看起来像这样:
MockRepository mocks = new MockRepository();
IAuthenticateDA mockAuthenticateDA = mocks.StrictMock<IAuthenticateDA>();
string customerId;
string userId;
Expect.Call(mockAuthenticateDA.GetScope()).Return(null);
Expect.Call(mockAuthenticateDA.Check(
null,
"orgadata",
"test",
"test",
"branch",
"customer",
out customerId,
out userId)).Return(eCheckResult.cOK);
Expect.Call(mockAuthenticateDA.GetRightAssignment(null, "userId"))
.Return(MockupDA.Rights);
这是我的错误消息:
Die Orgadata.Auth.TestUnits.ServiceTest.TestBLAuthenticate-Testmethode hat eine Ausnahme ausgelöst: System.InvalidOperationException: Previous method 'IAuthenticateDA.GetScope();' requires a return value or an exception to throw.
Ergebnis StackTrace:
bei Rhino.Mocks.Impl.RecordMockState.AssertPreviousMethodIsClose()
bei Rhino.Mocks.Impl.RecordMockState.MethodCall(IInvocation invocation, MethodInfo method, Object[] args)
bei Rhino.Mocks.MockRepository.MethodCall(IInvocation invocation, Object proxy, MethodInfo method, Object[] args)
bei Rhino.Mocks.Impl.Invocation.Actions.RegularInvocation.PerformAgainst(IInvocation invocation)
bei Rhino.Mocks.Impl.RhinoInterceptor.Intercept(IInvocation invocation)
bei Castle.DynamicProxy.AbstractInvocation.Proceed()
bei Castle.Proxies.IAuthenticateDAProxy619e9a2b8594464d89e95c4149fb2ab3.IDisposable.Dispose()
bei Microsoft.Practices.Unity.ContainerControlledLifetimeManager.Dispose(Boolean disposing) in c:'tfs'EL'V5-SL'UnityTemp'Compile'Unity'Unity'Src'Lifetime'ContainerControlledLifetimeManager.cs:Zeile 76.
bei Microsoft.Practices.Unity.ContainerControlledLifetimeManager.Dispose() in c:'tfs'EL'V5-SL'UnityTemp'Compile'Unity'Unity'Src'Lifetime'ContainerControlledLifetimeManager.cs:Zeile 60.
bei Microsoft.Practices.ObjectBuilder2.LifetimeContainer.Dispose(Boolean disposing) in c:'tfs'EL'V5-SL'UnityTemp'Compile'Unity'Unity'Src'ObjectBuilder'Lifetime'LifetimeContainer.cs:Zeile 103.
bei Microsoft.Practices.ObjectBuilder2.LifetimeContainer.Dispose() in c:'tfs'EL'V5-SL'UnityTemp'Compile'Unity'Unity'Src'ObjectBuilder'Lifetime'LifetimeContainer.cs:Zeile 79.
bei Microsoft.Practices.Unity.UnityContainer.Dispose(Boolean disposing) in c:'tfs'EL'V5-SL'UnityTemp'Compile'Unity'Unity'Src'UnityContainer.cs:Zeile 466.
bei Microsoft.Practices.Unity.UnityContainer.Dispose() in c:'tfs'EL'V5-SL'UnityTemp'Compile'Unity'Unity'Src'UnityContainer.cs:Zeile 449.
bei Orgadata.Framework.IoC.Unity.TransientContainerProvider.Dispose(Boolean disposing) in x:'sourcen'Services'Framework'Orgadata.Framework.IoC.Unity'TransientContainerProvider.cs:Zeile 101.
bei Orgadata.Framework.IoC.Unity.TransientContainerProvider.Dispose() in x:'sourcen'Services'Framework'Orgadata.Framework.IoC.Unity'TransientContainerProvider.cs:Zeile 111.
bei Orgadata.Auth.TestUnits.ServiceTest.TestBLAuthenticate() in x:'sourcen'Services'Authentification'Orgadata.Auth.TestUnits'ServiceTest.cs:Zeile 168.
Rhino Mocks 需要你记录你的期望,所以你需要把它们包装在一个 using 块中。
using (mocks.Ordered())
{
Expect.Call(mockAuthenticateDA.GetScope)
.Return(null);
Expect.Call(() => mockAuthenticateDA.Check(
null, "orgadata", "test", "test", "branch", "customer",
out customerId, out userId))
.Return(eCheckResult.cOK);
Expect.Call(() => mockAuthenticateDA.GetRightAssignment(null, "userId"))
.Return(MockupDA.Rights);
}
mocks.ReplayAll();
using (mocks.Playback())
{
var result = testClass.Authenticate(identity, identityReference);
}
请注意ReplayAll
需要明确将期望标记为已记录,因为mocks.Ordered()
本身不会开始记录。您也可以使用块将mocks.Ordered
包装在外部开始记录中并删除ReplayAll
:
using (mocks.Record())
{
using (mocks.Ordered())
{
Expect.Call(mockAuthenticateDA.GetScope)
.Return(null);
Expect.Call(() => mockAuthenticateDA.Check(
null, "orgadata", "test", "test", "branch", "customer",
out customerId, out userId))
.Return(eCheckResult.cOK);
Expect.Call(() => mockAuthenticateDA.GetRightAssignment(null, "userId"))
.Return(MockupDA.Rights);
}
}
using (mocks.Playback())
{
var result = testClass.Authenticate(identity, identityReference);
}
这段代码甚至不应该编译。
Expect.Call
需要一个Action
,所以你需要这样做:
Expect.Call(mockAuthenticateDA.GetScope)
.Return(null);
Expect.Call(() => mockAuthenticateDA.Check(
null, "orgadata", "test", "test", "branch", "customer",
out customerId, out userId))
.Return(eCheckResult.cOK);
Expect.Call(() => mockAuthenticateDA.GetRightAssignment(null, "userId"))
.Return(MockupDA.Rights);