如何模拟包含使用Block的方法?

时间:2013-10-08 08:08:23

标签: c# .net unit-testing dependency-injection rhino-mocks

我是嘲弄单位测试的新手。

我有这种方法:

    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;
        }
    }

DataAccess是一个声明如下的接口:

   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.

2 个答案:

答案 0 :(得分:0)

这段代码甚至不应该编译。

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);

答案 1 :(得分:0)

Rhino Mocks要求您记录您的期望,因此您需要将它们包装在使用块中。

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