Выходной параметр Mocking SQL - PullRequest
5 голосов
/ 10 июня 2010

Я высмеял пару методов моего уровня доступа к данным, но в некоторых методах установлено значение выходного параметра 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, возвращаемое значение параметра устанавливается, но я понятия не имею, как это смоделировать

Ответы [ 3 ]

2 голосов
/ 10 июня 2010

Я думаю, вы поступаете неправильно. Ваш интерфейс 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 может даже не быть базой данных: это может быть текстовый файл на диске, веб-служба, макет или что-то еще.

Насмешка над 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);
}
0 голосов
/ 09 июля 2012

Я заглушил это, используя метод 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);

Ответ, возможно, немного запоздал для вашего проекта, но надеюсь, что это кому-нибудь поможет ...

Griff

0 голосов
/ 10 июня 2010

Я не думаю, что вы можете поиздеваться над этим, потому что это обычный SqlParameter (конкретный класс), а не параметр out / ref в смысле .Net.Я бы попытался просто установить значение параметра в поддельном вызове в dal (я не проверял синтаксис, но уверен, что вы поняли):

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