Я пишу модульные тесты для Spring Framework 2.5, используя JUnit.Более конкретно, я использую MockHttpServletRequest для тестирования моих контроллеров.Я столкнулся с проблемой, тестируя определенный сценарий.
Приложение редактировало объекты, сохраненные в Hibernate.Объекты работают примерно так:
Class Workflow {
... various properties and methods
Long workflowId; // primary key for this object
Long subclassId; // foreign key to another class
String subclassType; // what kind of other class?
}
Class Request {
.. various other properties and methods
Long subclassId; // primary key for this object
Long workflowId; // foreign key to Workflow
}
Рабочий процесс всегда привязан к одному, и только один, Запрос и Запрос всегда привязан к одному и только одному Рабочему процессу.Однако существует несколько объектов / таблиц, с которыми Workflow может ссылаться, поэтому subclassType должен отслеживать, какую другую таблицу искать. Таким образом, это немного похоже на запрос, наследуемый от / внедряющий Workflow, но база данных хранит их вотдельные таблицы, поэтому Java была реализована как отдельные классы.
Я не писал этот беспорядок.Я поддерживаю это.И он широко используется, с несколькими различными приложениями и типами subclassTypes, поэтому существуют ограничения на то, сколько «очистки» я могу сделать.
Рассматриваемое веб-приложение помещало объект Workflow в HttpSession, но редактировал Запрос вформа.Когда кто-то открывал несколько окон / вкладок с разными запросами в каждом окне, объект рабочего процесса из последнего открытого перезаписывал любые ранее открытые (сеансы привязаны к файлам cookie, только один набор файлов cookie для домена, совместно используемыйВСЕ окна в веб-браузере).Если они отправили форму для первого Запроса, объект Workflow из последнего (извлеченного из HttpSession) был записан с отправленным Запросом (НЕ правильным), что повредило данные в базе данных.
Мыв итоге возникли запросы, к которым было подключено несколько рабочих процессов, и запросы, к которым не было подключено ни одного рабочего процесса.
Очевидным решением было переписать приложение, чтобы оно никогда не сохраняло рабочий процесс в HttpSession.workflowId - одно из полей в Запросе;мы сохранили это в форме через скрытое поле.Да, мы чаще обращаемся к базе данных, но мы не пересекаем наши записи.
Такова ситуация.Теперь вопрос: как вы смоделируете это в JUnit?Чтобы никто в будущем не столкнулся с этой ситуацией снова?
Мы используем MockHttpServletRequest, подключая значения форм и отправляя их, используя AnnotationMethodHandlerAdapter и объект Controller.Как пример:
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
AnnotationMethodHandlerAdapter handler = new AnnotationMethodHandlerAdaptor();
RequestFormController controller = new RequestFormController();
request.setMethod("GET");
request.setRequestURI("/EditRequest.do"); // handled by the RequestFormController
request.setParameter("wfId", Long.toString(wfid)); // wfId is the workflow ID of a valid Workflow with an attached Request
ModelAndView mv = handler.handle(request, response, controller);
request.setParameter("wfId", mv.getModel().get("wfId");
request.setParameter("requestText", "blah blah blah");
request.setMethod("POST");
request.setRequestURI("/UpdateRequest.do"); // handled by the RequestFormController
mv = handler.handle(request, response, controller);
Это все довольно просто, Spring / JUnit.Проблема в том, что для открытия чего-либо в двух разных вкладках / окнах вам нужно иметь два разных запроса, каждый из которых имеет свой собственный HttpSession.Однако в веб-браузере эти два разных запроса используют одни и те же файлы cookie, что означает, что они используют одну и ту же информацию сеанса.Как заставить JUnit смоделировать это?
Я могу скопировать куки-файлы из одного в другой, но это не выдает ошибку.MockHttpServletRequest по-прежнему хранит информацию HttpSession отдельно.Я с трудом копирую атрибуты HttpSession из одного в другой.Поскольку я так и сделал, я не могу понять, что это также раскрывает ошибку.
Есть предложения?Это очень реальная проблема, и MockHttpServletRequest и все другие связанные с JUnit вещи, которые мы делаем, точно не моделируют реальный мир Tomcat и веб-браузеров.
Peace.