2010-06-10 61 views
5

我嘲笑了我的數據訪問層的幾個方法,但在某些方法中設置了SQL輸出參數的值。我怎麼嘲笑這個?嘲笑SQL輸出參數

方法:

var wrappedParameters = new SqlParameter[3]; 
      wrappedParameters[0] = new SqlParameter("@username",username); 
      wrappedParameters[1] = new SqlParameter("@password",password); 
      wrappedParameters[2] = new SqlParameter("returnValue",SqlDbType.Int) { Direction =ParameterDirection.ReturnValue }; 

      dal.ExecuteUsingStoredProcedure("GetUser", wrappedParameters); 

嘲諷(我嘗試使用 「OUTREF」,但不工作):

using (mocks.Record()) 
     { 
      Expect.Call(dal.ExecuteUsingStoredProcedure("",> null)).Return(true).IgnoreArguments().OutRef(1); 
     } 

但沒有工作。當我執行SP GetUser時,參數返回值被設置,但我不知道如何模擬這個

+0

嘗試使用IDbParameter過的SqlParameter如果可能,那麼你可以嘲笑你的心臟的內容。 – 2010-06-17 19:59:54

回答

2

我覺得你以這種錯誤的方式去做。您的DAL界面應如下所示:

/// <summary> 
/// Models a service which holds the user information. 
/// </summary> 
public interface IUserRepository 
{ 
    /// <summary> 
    /// Gets the user with the given name, or <c>null</c> if no user with 
    /// that name and password exists. 
    /// </summary> 
    /// <exception cref="IOException"> 
    /// An I/O problem occurred while accessing the repository. 
    /// </exception> 
    User TryGetUser(string name, string password); 
} 

DAL抽象現在隱藏了使用存儲過程的事實。事實上,DAL甚至可能不是數據庫:它可能是磁盤上的文本文件,web服務,模擬或其他任何文件。

嘲笑DAL以測試使用DAL的代碼現在變得微不足道了。我所選擇的這些實施例中的登錄畫面作爲被測系統的view model(又名presentation model):

[Test] 
public void Login_sets_user_and_goes_to_main_screen_when_TryGetUser_not_null() 
{ 
    var userRepositoryStub = MockRepository.GenerateStub<IUserRepository>(); 
    var user = new User(...); 
    userRepositoryStub.Stub(x=>x.GetUserByName("foo","bar")).Return(user); 
    var sessionStub = MockRepository.GenerateStub<ISession>(); 
    var loginScreenViewModel = 
     new LoginScreenViewModel(sessionStub, userRepositoryStub); 

    loginScreenViewModel.UserName = "foo"; 
    loginScreenViewModel.Password = "bar"; 
    loginScreenViewModel.Login(); 

    userRepositoryStub.AssertWasCalled(x=>x.TryGetUser("foo","bar")); 
    sessionStub.AssertWasCalled(x=>x.ShowMainScreen()); 
    Assert.AreEqual(user, session.User); 
} 

[Test] 
public void Login_shows_error_when_TryGetUser_returns_null() 
{ 
    var userRepositoryStub = MockRepository.GenerateStub<IUserRepository>(); 
    var sessionStub = MockRepository.GenerateStub<ISession>(); 
    var loginScreenViewModel = 
     new LoginScreenViewModel(sessionStub, userRepositoryStub); 

    loginScreenViewModel.UserName = "foo"; 
    loginScreenViewModel.Password = "bar"; 
    loginScreenViewModel.Login(); 

    Assert.AreEqual(loginScreenViewModel.Error, 
     "User 'foo' does not exist or password is incorrect")); 
    userRepositoryStub.AssertWasCalled(x=>x.TryGetUser("foo","bar")); 
    sessionStub.AssertWasNotCalled(x=>x.ShowMainScreen()); 
    Assert.IsNull(session.User); 
} 
0

我不認爲你可以嘲笑它,因爲它是一個普通的SqlParameter(具體類),它不是.Net意義上的out/ref參數。我會嘗試是簡單地設置在嘲笑調用DAL參數的值(我沒有檢查語法,但我相信你的想法):

using (mocks.Record()) 
     { 
      Expect.Call(dal.ExecuteUsingStoredProcedure("",null)).Return(true).IgnoreArguments().Do(x => wrappedParameters[2].Value = 1; true); 
     } 
0

我使用「WhenCalled」方法對此進行了樁存。

在我的代碼(待測試)中,我首先創建連接和命令並添加三個參數,其中第三個參數是我的輸出參數。然後我在這個上調用「ExecuteCommand」....我不會通過這個代碼,因爲我認爲它相當標準(ExecuteCommand以命令對象作爲參數)。

在我的測試中,我創建了一個存根我的SQL數據服務,並計劃就使這臺參數的值:

var sqlService = MockRepository.GenerateStub<ISqlDataService>(); 
sqlService.Stub(s => s.ExecuteCommand(null)) 
    .IgnoreArguments() 
    .WhenCalled(s => ((SqlCommand)s.Arguments[0]).Parameters[2].Value = expectedValue) 
    .Return(0); 

答案很可能有點晚了你的項目,但希望這幫助別人......

格里夫