簡體   English   中英

模擬SQL輸出參數

[英]Mocking SQL output parameter

我模擬了數據訪問層的幾種方法,但在某些方法中,設置了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時,設置了param返回值,但我不知道如何模擬它

我認為你這是錯誤的做法。 您的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的代碼現在變得微不足道。 在這些示例中,我選擇了登錄屏幕的視圖模型 (也稱為演示模型 )作為被測系統:

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

我使用“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);

對你的項目來說,答案可能有點晚了,但希望這有助於某些人......

格里夫

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM