Насмешка и вызовы API Win32

Поздний пост, но для тех, кто искал этот пост.

Представьте себе:

    [Authorize(Roles = "Administrator")]
    [Authorize(Roles = "Director")]
    [Authorize(Roles = "Human Resources")]
    [HttpGet]
    public ActionResult GetUserData(string UserIdGuidKey)
    {
        if (UserIdGuidKey!= null)
        {
            var guidUserId = new Guid(UserIdGuidKey);
            var memuser = Membership.GetUser(guidUserId);
            var profileuser = Profile.GetUserProfile(memuser.UserName);
            var list = new {
                              UserName = memuser.UserName,
                              Email = memuser.Email ,
                              IsApproved = memuser.IsApproved.ToString() ,
                              IsLockedOut = memuser.IsLockedOut.ToString() ,
                              LastLockoutDate = memuser.LastLockoutDate.ToString() ,
                              CreationDate = memuser.CreationDate.ToString() ,
                              LastLoginDate = memuser.LastLoginDate.ToString() ,
                              LastActivityDate = memuser.LastActivityDate.ToString() ,
                              LastPasswordChangedDate = memuser.LastPasswordChangedDate.ToString() ,
                              IsOnline = memuser.IsOnline.ToString() ,
                              FirstName = profileuser.FirstName ,
                              LastName = profileuser.LastName ,
                              NickName = profileuser.NickName ,
                              BirthDate = profileuser.BirthDate.ToString() ,
            };
            return Json(list, JsonRequestBehavior.AllowGet);
        }
        return Redirect("Index");
    }

Как вы можете видеть, я использую функцию C # 3.0 для создания универсальных «Авто». Это немного лениво, но мне это нравится, и это работает. Просто примечание: Profile - это пользовательский класс, который я создал для своего проекта веб-приложения.

7
задан Ajay 25 January 2018 в 06:09
поделиться

5 ответов

Что касается (2), большинство функций Win32, которые принимают строковые параметры, уже имеют свою общую форму, определенную как макрос, например, из WinUser.h:

WINUSERAPI
int
WINAPI
MessageBoxA(
    __in_opt HWND hWnd,
    __in_opt LPCSTR lpText,
    __in_opt LPCSTR lpCaption,
    __in UINT uType);
WINUSERAPI
int
WINAPI
MessageBoxW(
    __in_opt HWND hWnd,
    __in_opt LPCWSTR lpText,
    __in_opt LPCWSTR lpCaption,
    __in UINT uType);
#ifdef UNICODE
#define MessageBox  MessageBoxW
#else
#define MessageBox  MessageBoxA
#endif // !UNICODE

Вы, конечно, можете добавить заголовок к ваш проект, который переопределяет функции API, которые вы хотите моделировать:

#ifdef UNITTEST
#undef MessageBox
#define MessageBox UnitTestMessageBox
#endif

Переопределив имя, вы можете избежать разбрасывания большого количества условной компиляции по всему исходному коду.

9
ответ дан 6 December 2019 в 12:53
поделиться

Я бы рекомендовал инкапсулировать вызовы API в хорошо продуманные интерфейсы. Затем вы можете проверить свою бизнес-логику, используя фиктивные объекты или тестовые двойники. Вам не нужно тестировать сам Windows API, потому что это уже сделано миллионами работающих приложений Windows.

Модульное тестирование никогда не должно включать доступ к оборудованию, если вы не разрабатываете оборудование. Это просто проверка вашего логического кода.

4
ответ дан 6 December 2019 в 12:53
поделиться

Используйте перехватчик Deviare API , перехватите все вызовы API и выполните модульный тест.

2
ответ дан 6 December 2019 в 12:53
поделиться

По возможности, было бы лучше сделать так, чтобы события происходили, не изменяя вызовы Win32.

Например, вместо создания собственного CreateFile , который завершится ошибкой, потому что файл уже используется, вместо этого откройте файл исключительно в другой программе (которую вы вызываете из своего модульного теста), а затем запустите модульный тест.

Если вы должны имитировать какой-то вызов Win32, то, вероятно, было бы лучше создать библиотеку-оболочку вокруг наборов вызовов Win32, которые вы хотите сделать. Тогда вы не навредите кодовой грамотности основной логики.

-1
ответ дан 6 December 2019 в 12:53
поделиться

В конце концов, я действительно использовал подход, ориентированный на C #, и создал интерфейсы, которые позволили бы мне заглушить вызовы Win32, которые я хотел использовать.

Например, у меня был один, названный IRegistryOperations , которые содержали RegOpenKey , RegQueryValueEx , RegNotifyChange и несколько других, которые я использовал. В конструкторе был создан конструктор по умолчанию, который просто вызывает настоящую функцию, но у меня также был конструктор, который использовал интерфейс, чтобы я мог имитировать хитрые значения и т. Д.

(Не уверен, что это плохой этикет - отвечать на мой собственный вопрос, хотя )

2
ответ дан 6 December 2019 в 12:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: