2015-11-12 2 views
0

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

Это код:

// GET: Books/Archive 
public async Task<ActionResult> Archive() 
{ 
    var usersBooks = await _bookManager.GetArchiveBooks(Guid.Parse(HttpContext.User.Identity.GetUserId())); 

    var result = usersBooks.Select(ConvertArchiveBookToViewModel).ToList(); 

    return View(new ArchiveViewModel 
     { 
      Books = result 
     }); 
} 

Любой ответ будет очень полезным и спасибо :)

+2

Из [Справка] (http://stackoverflow.com/help/on-topic): Вопросы, требующие помощи в выполнении домашних заданий, должны содержать резюме работы, которую вы сделали до сих пор, для решения проблемы, а также описание трудность, которую вы решаете. –

+0

Вы можете, конечно, посмотреть на IoC как Autofac и использовать инфраструктуру Moq, чтобы издеваться над классом _bookManager. –

ответ

3

Первая вещь первая ... Вы должны издеваться _bookManager как зависимость для этого метода.

Откуда: _bookManager? Предположительно это свойство класса. Поэтому он должен предоставить некоторые средства для использования макета. Вы, , должны использовать инъектор конструктора, но если вы не знакомы с зависимостями проводки в ASP.NET MVC, тогда он может оказаться слишком сложным. Инъекционное свойство должно работать так же хорошо. Что-то вроде этого:

public class MyController 
{ 
    private SomeType _bookManager; 
    public SomeType BookManager 
    { 
     get { return _bookManager; } 
     set { _bookManager = value; } 
    } 

    public async Task<ActionResult> Archive() 
    { 
     // your method 
    } 
} 

Предположительно также есть код в другом месте в тот класс, который в противном случае инициализирует _bookManager перед его использованием. Вы захотите немного изменить эту логику, чтобы она не перезаписывала любые предоставленные макеты. Один шаблон, который часто хорошо работает для меня, - это использование самого свойства, даже внутреннего для класса, и ленивое инициализация в свойстве. Что-то вроде этого:

public class MyController 
{ 
    private SomeType _bookManager; 
    public SomeType BookManager 
    { 
     get 
     { 
      if (_bookManager == null) 
       _bookManager = new SomeType(); 
      return _bookManager; 
     } 
     set { _bookManager = value; } 
    } 

    public async Task<ActionResult> Archive() 
    { 
     // IMPORTANT: Use "BookManager" instead of "_bookManager" 
    } 
} 

Идея заключается в том, что если вы передаете издеваются (или любой реализации зависимостей) для BookManager то код будет использовать. В противном случае он будет использовать то, что вы сейчас используете.

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

Целью макета является обеспечение ожидаемого, определенного поведения. Это связано с тем, что ...

Вы тестируете Archive(). Вы не тестирование BookManager.GetArchiveBooks()

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

В широком смысле, ваш тест будет выглядеть примерно так:

// arrange 
var bookManager = MockRepository.GenerateMock<SomeType>(); 
// TODO: configure the object to return a known result from GetArchiveBooks() 
var controller = new MyController(); 
controller.BookManager = bookManager; 

// act 
var result = await controller.Archive(); 

// assert 
// TODO: inspect the result to ensure it contains what you expect 

Для насмешливых библиотек по вашему выбору, посмотрят на некоторых примерах для создания «заглушки» для вызываемого метода (в данном случае GetArchiveBooks()).

Для проверки результата сначала вам нужно пройти этот тест в отладчике и посмотреть, что на самом деле имеет result. Результат обзора имеет много свойств, и я не знаю их с головы. Но если вы проверите его в отладчике, вы сможете найти свою модель в одном из этих свойств, а также потенциально другие вещи, которые вы могли бы проверить, если хотите. (В зависимости от того, сколько вещей вы хотите утверждать в этом тесте.)

Целью здесь является удостовериться, что возвращенная модель точно, что вы ожидаете, что она будет основана на известном поведении издевательства. Если это так, то метод проходит тест.


Edit: я только что заметил вторую зависимость в методе: реализации

HttpContext.User.Identity.GetUserId() 

Современного ASP.NET MVC могут предоставить некоторые полезные способы поиздеваться HttpContext, а также, хотя я не тоже знакомы с этим с моей головы. В худшем случае сценарий заключается в том, что вы просто выставляете другое инъекционное свойство, чтобы издеваться над ним. Что-то вроде этого:

private string _userID; 
public string UserID 
{ 
    get 
    { 
     if (string.IsNullOrWhiteSpace(_userID)) 
      _userID = HttpContext.User.Identity.GetUserId(); 
     return _userID; 
    } 
    set { _userID = value; } 
} 

Тогда в вашем методе действия вы будете использовать это свойство вместо вызова HttpContext непосредственно. И в вашем тесте, как часть шага «Аранжировка», вы будете снабжать насмешливую строку. Что довольно легко:

controller.UserID = "testUser"; 

Как вы можете видеть в этой точке, проверяемость является все о управления зависимостями. Каждая отдельная проверяемая часть кода должна быть изолирована от любых зависимостей, независимо от того, насколько они малы. (Например, получение идентификатора пользователя от HttpContext.) "Invert" those dependencies, чтобы разрешить коду предоставлять информацию, а не иметь тестовый код для получения информации.

+0

большое спасибо, ваш ответ был очень полезен :) –

Смежные вопросы