MVC3 Тестирует действие создания и передает обратно созданный объект — TempData?

#asp.net-mvc-3 #testing #nunit #massive

#asp.net-mvc-3 #тестирование #nunit #массивный

Вопрос:

Как передать успешно созданный объект из Create action с помощью RedirectToAction?

Все выглядит хорошо в действии, просто не могу ссылаться на него в тесте.

   [Test]
    public void a_new_trick_should_be_saved_to_db_when_date_created_field_is_blank_and_set_to_now() {
        var controller = new TricksController();
        var formCollection = new FormCollection() {
                                                        { "Name", "test" },
                                                        { "Description", "test desc" },
                                                        { "Votes", "" },
                                                        { "VideoURL", "" },
                                                        { "DateCreated", ""}
                                                  };
        //on success result is always null
        var result = controller.Create(formCollection) as ViewResu<

        //**this will never work as result is null when success
        var newlyCreatedThing = result.TempData["newlyCreatedThing"];

        //on fail result holds the errors list
        string errorMessage = "";
        if (result != null)
            errorMessage = result.TempData["Error"].ToString();
        Assert.IsEmpty(errorMessage);
    }
  

и метод действия:

   [HttpPost]
    [ValidateAntiForgeryToken]
    [Authorize(Roles = "Administrator")]
    public ActionResult Create(FormCollection collection)
    {
        var itemToCreate = _tricksTable.CreateFrom(collection);
        try
        {
            //validation enforced on model (as an override on Massive)
            var expandoNewlyCreatedTrick = _tricksTable.Insert(itemToCreate);

            //pass back newly created trick so that tests can make sure data is right
            TempData["newlyCreatedThing"] = expandoNewlyCreatedTrick;
            return RedirectToAction("Index");
        }
        catch (Exception ex)
        {
            TempData["Error"] = "There was an error adding the trick: "  ex.Message;
            return View(itemToCreate);
        }
    }
  

Комментарии:

1. 1- Поставьте точку останова в первой строке действия и посмотрите, в какой строке она прерывается, затем вы можете отследить ее и выяснить, почему она возвращает Null в результат теста.

2. 2- В модульном тестировании вам не разрешено совершать транзакции с БД, вы должны подделать метод Insert и избегать записи в БД. Хороший пример того, как подделать методы: nerddinnerbook.s3.amazonaws.com/Part12.htm

3. Спасибо @Amir978 — я пока отказываюсь от этого. Я подозреваю, что TempData не работает, поскольку я не в HttpContext и, следовательно, не в сеансе.. так что не могу получить доступ к tempdata. Повторное модульное тестирование — я экспериментирую с попаданием в БД во всех моих модульных тестах и приятно удивлен тем, насколько это быстро, и простотой отсутствия необходимости издеваться / заглушки / подделки.

4. Я имею в виду, что когда вы запускаете метод, который выполняет транзакцию с DB, вы вносите изменения в DB, и это абсолютно неправильно. Представьте сценарий, в котором вам нужно добавить пользователя. Если вы добавляете / удаляете пользователя в модульном тестировании, вам придется добавлять / удалять много пользователей, и ваша БД очень скоро будет заполнена ненужными данными!

5. Спасибо @Amir978, я понимаю, о чем вы говорите. Это еще одна стратегия, которую я использую… из того, что я слышал, больше похоже на Ruby on Rails. Каждый модульный тест в этом проекте начинается с известного экземпляра данных (все это относится к версии db для разработчиков), который генерируется методом [SetUp]. Я скоро буду писать об этом в блоге. По завершении будет добавлена ссылка.