Почему этот модульный тест asp.net MVC не проходит? - PullRequest
0 голосов
/ 22 мая 2010

Я много редактировал и упрощал этот вопрос.

Если у меня есть этот метод на моем HomeController:

    public ActionResult Strangeness( int id )
    {
        StrangenessClass strangeness = null;

        if( id == 1 )
        {
            strangeness = new StrangenessClass() { Name="Strangeness", Desc="Really weird behavior" };
        }

        return View( strangeness );
    }

И есть этот класс:

public class StrangenessClass
{
    public string Name { get; set; }
    public string Desc { get; set; }
}

Почему этот модульный тест не пройден?

    [TestMethod]
    public void Strangeness()
    {
        HomeController controller = new HomeController();

        ViewResult result = controller.Strangeness( 1 ) as ViewResult;
        var model = result.ViewData.Model;
        result = controller.Strangeness( 2 ) as ViewResult;
        model = result.ViewData.Model;

        Assert.IsNull( model );
    }

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

Если это неправильный способ проверки удалений, как бы вы это сделали? Вам не нужно убедиться, что запись была действительно удалена?

Ответы [ 2 ]

1 голос
/ 27 мая 2010

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

В любом случае, если вы проверите исходный код для MVC , вы найдете причину такого поведения:

protected internal virtual ViewResult View(string viewName, string masterName, object model)
{
    if (model != null)
    {
        base.ViewData.Model = model;
    }
    return new ViewResult { ViewName = viewName, MasterName = masterName, ViewData = base.ViewData, TempData = base.TempData };
}

Если модель нулевая, она не присваивается свойству ViewData.Model. Если вы хотите правильного поведения, создайте новый контроллер для вашего второго вызова HomeController.Strangeness.

0 голосов
/ 22 мая 2010

Не понятно, что вы тестируете. В разделе Arrange вашего тестового метода вы вызываете первое действие Delete, а в разделе Act вы вызываете второе. Так вы тестируете контроллер? Если да, то почему вы вызываете первый метод Delete в разделе Arrange?

И что такое переменная _stateService? Это интерфейс или вы действительно удаляете записи в базе данных в вашем модуле / интеграционном тесте?

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

Предполагая, что _stateService является интерфейсом, который можно смоделировать, и именно так я бы порекомендовал вам спроектировать ваш контроллер, ваш тест может выглядеть так (с использованием Rhino Mocks и MVCContrib.TestHelper ):

[TestClass]
public class DevisControllerTests : TestControllerBuilder
{
    private HomeController _sut; // Subject Under Test
    private IStateService _stateServiceStub; // Dependency of the SUT

    [TestInitialize()]
    public void MyTestInitialize()
    {
        _stateServiceStub = MockRepository.GenerateStub<IStateService>();
        _sut = new HomeController(_stateServiceStub);
        InitializeController(_sut); // this method comes from the base class TestControllerBuilder
    }

    [TestMethod]
    public void HomeController_Delete_Action_Should_Fetch_State_From_Db_And_Pass_It_To_The_View()
    {
        // arrange
        var id = 4;
        var expectedState = new State();
        _stateServiceStub.Stub(x => x.GetById(id)).Return(expectedState);

        // act
        var actual = _sut.Delete(id);

        // assert
        actual
            .AssertViewRendered()
            .WithViewData<State>()
            .ShouldBe(expectedState);
    }

    [TestMethod]
    public void HomeController_Delete_Action_Handler_Should_Return_Default_View_If_Model_Null()
    {
        // act
        var actual = _sut.Delete(null);

        // assert
        actual.AssertViewRendered();
    }

    [TestMethod]
    public void HomeController_Delete_Action_Handler_Should_Return_View_If_Exception_Thrown_From_Service()
    {
        // arrange
        var model = new State();
        _stateServiceStub.Stub(x => x.Delete(model)).Throw(new Exception("oops"));

        // act
        var actual = _sut.Delete(state);

        // assert
        actual
            .AssertViewRendered()
            .WithViewData<State>()
            .ShouldBe(model);
    }


    [TestMethod]
    public void HomeController_Delete_Action_Handler_Should_Redirect_If_Model_Successfully_Deleted()
    {
        // arrange
        var model = new State();

        // act
        var actual = _sut.Delete(state);

        // assert
        actual
            .AssertActionRedirect()
            .ToAction<HomeController>(c => c.Index());

        _stateServiceStub.AssertWasCalled(x => x.Delete(model));
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...