mongodb+mockito не работает вместе?

Я пытаюсь настроить макеты для mongodb в своем java-коде и получаю следующее исключение:

org.mockito.exceptions.misusing.WrongTypeOfReturnValue:
DBCursor$$EnhancerByMockitoWithCGLIB$$fc4f0e22 cannot be returned by getOptions()
getOptions() should return int

Строка кода, которая генерирует это:

when(col.find(query)).thenReturn(cursor);

Где col — это фиктивный DBCollection, запрос — фиктивный DBObject, а cursor — фиктивный DBCursor.

Я нашел следующее очень расплывчатое, но, вероятно, актуальное описание проблемы:

http://osdir.com/ml/mongodb-user/2010-08/msg02102.html


person Kevin    schedule 04.11.2011    source источник


Ответы (1)


Только что нашел проблему, метод find(DBObject obj) является окончательным в DBCollection:

http://grepcode.com/file/repo1.maven.org/maven2/org.mongodb/mongo-java-driver/2.1/com/mongodb/DBCollection.java

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

person Kevin    schedule 04.11.2011
comment
Есть такая поговорка: не издевайтесь над шрифтом, которым не владеете! - person Brice; 05.11.2011
comment
@Brice: На самом деле я почти уверен, что вы должны издеваться над типами, которыми вы не владеете. Так что я не вижу твоей точки зрения. - person Kevin; 05.11.2011
comment
Ну, это неправильно по нескольким причинам (однако могут быть исключения). Тип, которым вы не владеете, ведет себя по-своему, не пытайтесь высмеивать его. Вместо этого создайте тип интеграции, использующий реальные типы. Прочтите этот пост, он объясняет лучше и тщательнее, чем этот комментарий, почему я говорю Не высмеивайте шрифт, которым вы не владеете! - person Brice; 05.11.2011
comment
Прямые вызовы внешних служб создают медленные и ненадежные модульные тесты, поэтому существуют макеты. Интеграционные тесты, без сомнения, необходимы, но они отделены от модульных тестов. - person Kevin; 06.11.2011
comment
Разве тесты MongoDB не относятся к категории интеграционных тестов? ;) Если все ваши тесты должны вызывать внешние службы, у вас могут быть проблемы с дизайном или сталкиваться с устаревшим дизайном. Если вам действительно нужно имитировать внешние системы, а затем обернуть их в типы, которыми вы действительно владеете, эти оболочки затем будут протестированы как интеграционные тесты. Другой объект можно протестировать, как обычно, с помощью макетов, если это необходимо. И, кстати, Не имитируйте шрифт, которым вы не владеете — это одно из правил mockito, которое существует уже очень давно. - person Brice; 06.11.2011
comment
Я обернул вызовы монго, но в этом коде оболочки все еще есть некоторая бизнес-логика, которую мне нужно для модульного тестирования. Вот почему я издеваюсь над монго. - person Kevin; 06.11.2011
comment
Обертка + Бизнес-логика в одном и том же объекте мне кажется неправильным. Оба не имеют ничего общего в одном и том же месте, попробуйте пересмотреть свой дизайн с учетом разделения проблем. Бизнес-логика может быть перемещена в обратные вызовы, стратегии или что-то еще, таким образом вы можете только издеваться над своим кодом. - person Brice; 06.11.2011
comment
Брайс: Я читал вашу статью, но я не согласен с тем, что внешние сервисы не следует высмеивать. Я согласен, что если вы чертовски полны решимости отделить бизнес-логику от вызовов монго, ваше предложение верно. Проблема в том, что в этот момент существует только оболочка mongo, поэтому я могу сказать, что я не издеваюсь над внешними вызовами; это не дает никакой другой ценности вообще. Может быть, вы имеете в виду, что я должен сделать это dao, чтобы я мог позже добавить другую реализацию, не меняя уровень службы, но этого просто не произойдет. Таким образом, слой дао просто добавляет сложности/многословия, но не приносит реальной пользы. - person Kevin; 06.11.2011
comment
Это ваш выбор, но многие люди согласны с этой аксиомой, есть вопрос здесь по этому поводу тема. Что касается отделения бизнеса от уровня доступа, мне вообще не нравятся DAO или службы доступа к данным, тем не менее, существует техническая несоответствие между вашим бизнес-кодом и чистый общий уровень данных сам по себе неплохая идея. Особенно в наши дни, когда вокруг NoSQL много инноваций. Я не говорю, что вы должны добавлять DAO, а скорее разделяете различные задачи вашего кода. - person Brice; 07.11.2011
comment
да, я читал это прошлой ночью. есть по крайней мере несколько человек (включая принятый ответ), которые считают, что обоснование, данное в сообщении Марка, имеет смысл для спящего режима и EntityManager, но может применяться или не применяться к другим случаям. Лично я не думаю, что это применимо к моему случаю. В любом случае, спасибо за ваш вклад, так как я не знал об этой философии. - person Kevin; 07.11.2011
comment
ОК, приятно знать, что это помогло :) Кстати, я хотел бы порекомендовать еще один пост в блоге, Джеймс Карр перечислил некоторые анти-паттерны test/TDD, это хорошее чтение: blog.james-carr.org/2006/11/03/tdd-anti-patterns - person Brice; 08.11.2011
comment
Спасибо за внимание к вашему решению - это сводило меня с ума! - person Erik Dietrich; 10.04.2012