Как внедрить объект mocked с помощью jmockit в управляемый объект spring с помощью метода @Transactional?
Я пишу тестовый случай TestNG в проекте spring и использую jmockit для моделирования зависимостей. Я сталкиваюсь с проблемой, которая заключается в том, что я не могу использовать Деэнкапсуляцию.setField чтобы задать зависимость для объекта, управляемого spring, содержащего метод @ Transactional, Ошибка:
В классе java отсутствует поле экземпляра с именем "dataLogManager".яз..отражать.Прокси
Мой пример кода, приведенный здесь,
Тестовый случай:
public class QueueManagerTest extends AbstractTestNGSpringContextTests {
@Autowired
private QueueManager queueManager;
@Autowired
private ApplicationContext context;
@Autowired
private TransInfoManager transInfoManager;
@Autowired
private Generator generator;
@Autowired
private MessageDTOFactoryBean messageDTOFactoryBean;
@Test(description="單元測試:寫入一筆Data資料,非邊界情況下(無待處理筆數)")
public void writeControlMessage(
@Mocked final TransInfoManager transInfoManager,
@Mocked final DataManager dataManager,
@Mocked final DataLogManager dataLogManager
) {
....
Deencapsulation.setField(queueManager, "dataLogManager", dataLogManager);
Deencapsulation.setField(queueManager, "dataManager", dataManager);
Deencapsulation.setField(queueManager, "transInfoManager", transInfoManager);
....
}
}
Обслуживание:
@Service
public interface QueueManager {
@Transactional
MessageDTO putDataIntoQueue(MessageDTO message);
}
Любой знает, как это сделать. решить эту проблему? Спасибо.
1 ответ:
Если вы хотите протестировать какой-то конкретный класс, реализующий интерфейс
QueueManager, то решение состоит в том, чтобы просто создать экземпляр класса непосредственно в тесте, а не использовать для этого Spring.Причина исключения заключается в том, что Spring фактически создает экземпляр класса proxy для Поля
queueManager, предназначенного для украшения реальной реализации (объект proxy делегирует каждый вызов метода другому объекту, который был бы экземпляром класса приложения на самом деле реализация интерфейсаQueueManager). Прокси-класс не содержит поля с именем "dataLogManager", поэтомуDeencapsulation.setField(...)не может его найти.Если первое решение, которое я упомянул, неприменимо, вы все равно можете позволить Spring выполнить создание экземпляра, при условии, что он также вводит поля внутри объекта
queueManager. Чтобы издеваться над классом, реализующимDataLogManager(и другие интерфейсы), используйте@Capturingвместо (или в дополнение к)@Mocked; это даст команду JMockit распространить издевательство на все классы реализации.