2010-06-10 57 views
5

Tôi đã chế nhạo một vài phương thức của lớp Truy cập dữ liệu của tôi, nhưng trong một số phương thức, giá trị của một tham số đầu ra SQL được thiết lập. Làm thế nào tôi có thể chế nhạo cái này?Tham số đầu ra SQL mô phỏng

Phương pháp:

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

Mocking (Tôi đã thử sử dụng "OutRef", nhưng điều đó không làm việc):

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

Nhưng đó didnt làm việc. Khi tôi thực hiện SP GetUser giá trị trả về param được thiết lập, nhưng tôi không biết làm thế nào để giả lập

+0

Cố gắng sử dụng IDbParameter trên SqlParameter khi có thể, sau đó bạn có thể giả lập nội dung trái tim của bạn. –

Trả lời

2

Tôi nghĩ rằng bạn đi về điều này một cách sai lầm. Giao diện DAL của bạn sẽ trông giống như sau:

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

Hiện tượng DAL ẩn hiện thực tế là quy trình được lưu trữ được sử dụng. Trong thực tế, DAL có thể thậm chí không phải là một cơ sở dữ liệu: nó có thể là một tập tin văn bản trên đĩa, một dịch vụ web, một mô hình hoặc bất cứ điều gì khác.

Giả mạo DAL để kiểm tra mã sử dụng DAL giờ đây trở nên tầm thường. Tôi đã chọn view model (aka presentation model) của một màn hình đăng nhập khi hệ thống được thử nghiệm trong các ví dụ:

[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

Tôi không nghĩ rằng bạn có thể giả lập nó, vì nó là một SqlParameter bình thường (lớp bê tông), và nó không tham số out/ref trong .Net sense. Những gì tôi sẽ cố gắng chỉ đơn giản là thiết lập giá trị của các tham số trong các cuộc gọi giả để dal (tôi đã không kiểm tra cú pháp, nhưng tôi chắc chắn bạn sẽ có được ý tưởng):

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

Tôi đã phân tích điều này bằng phương pháp "WhenCalled".

Trong mã của tôi (để được kiểm tra) đầu tiên tôi tạo kết nối và lệnh và thêm ba tham số, thứ ba trong số đó là tham số đầu ra của tôi. Sau đó tôi gọi "ExecuteCommand" về điều này .... Tôi sẽ không đi qua mã cho điều này vì tôi nghĩ rằng nó khá chuẩn (ExecuteCommand mất đối tượng lệnh như tham số của nó).

Trong thử nghiệm của mình, tôi tạo ra một stub cho dịch vụ dữ liệu sql của tôi và chương trình nó để này đặt giá trị của tham số:

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

của câu trả lời có lẽ là hơi muộn cho dự án của bạn, nhưng hy vọng điều này giúp ai đó ...

Griff

Các vấn đề liên quan