【问题标题】:Mock call object method (Mockito Junit5 Spring)模拟调用对象方法(Mockito Junit5 Spring)
【发布时间】:2020-07-13 11:19:22
【问题描述】:

我尝试模拟 thymeleaf 模板引擎。

我的测试课:

@ExtendWith(MockitoExtension.class)
@RunWith(JUnitPlatform.class)
public class MailServiceTest {
    @InjectMocks
    private MailService mailService;
    
    @Mock private JavaMailSender mailSender;
    @Mock private TemplateEngine templateEngine;
    
    @BeforeEach
    public void setMockOutput() {
        doReturn("<html>Template processed String</html>").when(templateEngine.process(any(String.class), any(IContext.class)));
    }

    @Test
    public void testNewMailBoxMail() throws MessagingException, IOException {
                
        mailService.newMailBoxMail("M.", "nom", "adresse@email.fr");

        ...
    }

我在处理方法参数 (org.mockito.exceptions.misusing.InvalidUseOfMatchersException) 上遇到了很多麻烦,我不确定它们是否正常。

当测试到达doReturn 行时,我得到了

java.lang.IllegalArgumentException: Template cannot be null
    at org.thymeleaf.util.Validate.notNull(Validate.java:37)
    at org.thymeleaf.TemplateSpec.<init>(TemplateSpec.java:314)
    at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1048)
    at fr.strasbourg.accountManagement.service.MailServiceTest.setMockOutput(MailServiceTest.java:50)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:515)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:115)
    at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.invokeMethodInExtensionContext(ClassTestDescriptor.java:436)
    at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.lambda$synthesizeBeforeEachMethodAdapter$14(ClassTestDescriptor.java:424)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeBeforeEachMethods$2(TestMethodTestDescriptor.java:136)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeBeforeMethodsOrCallbacksUntilExceptionOccurs(TestMethodTestDescriptor.java:156)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeBeforeEachMethods(TestMethodTestDescriptor.java:135)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:110)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:59)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:105)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:95)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:71)
    at java.util.ArrayList.forEach(ArrayList.java:1249)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:110)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:95)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:71)
    at java.util.ArrayList.forEach(ArrayList.java:1249)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:110)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:95)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:71)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:170)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:154)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:90)
    at org.junit.platform.runner.JUnitPlatform.run(JUnitPlatform.java:139)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:542)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:770)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)

有人可以帮我模拟 Thymeleaf 模板引擎吗?

感谢多米尼克

模板引擎作为 bean 注入到 MailService 对象中。 这是邮件服务代码:

@Service
public class MailService {
    @Autowired private JavaMailSender mailSender;
    @Autowired private TemplateEngine templateEngine;
    
    private static final String SUPPORT_EMAIL_ADDRESS = "Support@email.fr";
    
    public void newMailBoxMail(String pCivility, String pName, String pEmailAddress) throws MessagingException {
        // template context (model)
        final Context vContext = new Context();
        vContext.setVariable("civility", pCivility);
        vContext.setVariable("name", pName);
        vContext.setVariable("email", pEmailAddress);
        
        // create HTML from template
        final String vHtmlContent = templateEngine.process("html/NewMailbox.html", vContext);
        
        // create mail
        MimeMessage vMimeMessage = mailSender.createMimeMessage();
        
        MimeMessageHelper vMessage = new MimeMessageHelper(vMimeMessage, "UTF-8");
        vMessage.setSubject("Charte messagerie");
        vMessage.setFrom(SUPPORT_EMAIL_ADDRESS);
        vMessage.setTo(pEmailAddress);
        vMessage.setText(vHtmlContent, true);
        
        // send mail
        mailSender.send(vMimeMessage);
    }
}

【问题讨论】:

  • 你能显示MailService的代码吗? TemplateEngine 是否作为 bean 注入到 MailService 中?
  • 您确定需要 ExtendsWith 和 RunWith 注释吗?我认为 ExtendsWith 是 RunWith(Junit 4) 的 Juint5 版本。不要认为我们可以在同一个测试类上同时拥有两者。
  • 是的,TemplateEngine 是作为 bean 注入的
  • 你能试试/你试过了吗:doReturn("&lt;html&gt;Template processed String&lt;/html&gt;").when(templateEngine.process(any(), any()));?此方法也与问题有关:templateEngine.process(A, B)
  • @SandeepLakdawala 我从互联网上找到的样本中复制了 @extendWith@RunWith 注释。如果我删除@RunWith,我就不能再运行我的测试了。如果我删除@extendsWith,则不会进行任何模拟。

标签: java spring mockito thymeleaf junit5


【解决方案1】:

Mockito 不允许测试最终方法,并且模板引擎的 process() 是最终的。

但是你可以让它工作。就在你/src/test/resources 创建目录mockito-extensions。在内部创建文件org.mockito.plugins.MockMaker,内容为:mock-maker-inline

这行得通。

【讨论】:

    猜你喜欢
    • 2015-12-25
    • 1970-01-01
    • 2017-05-17
    • 1970-01-01
    • 2015-11-04
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多