使用Thymeleaf模板引擎对服务进行单元测试时的问题

ros*_*tow 4 unit-testing mockito spring-boot

在对服务进行单元测试时,我得到了nullPointerException,我不明白为什么?我正在使用Spring Boot。这是我提供模板的简单服务。我自动连接TemplateEngine组件。

@Service
public class TicketTemplatingService implements ITemplatingService{

    @Autowired
    private TemplateEngine templateEngine;

    /**
     * This method will return a ticket template
     */
    @Override
    public String buildHtmlTemplating(Object object, String templateName) {
        Ticket ticket= (Ticket)object;
        //Build the template
        Context context = new Context();
        context.setVariable("id", ticket.getId());
        context.setVariable("date", ticket.getDate());        
        return  templateEngine.process(templateName, context);
    }

}
Run Code Online (Sandbox Code Playgroud)

此类的单元测试如下:

@SpringBootTest
@RunWith(SpringRunner.class)
@ActiveProfiles("test")
public class TemplatingServiceTest {


    @InjectMocks
    private TicketTemplatingService ticketTemplatingService;

    @Mock
    private TemplateEngine templateEngine;

    @Before
    public void setup(){
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testHtmlTemplateReturnTheHtmlTemplate(){
        Ticket ticket= new Ticket();
        ticket.setId(1L);
        Date date=new Date();
        ticket.setDate(date);

        Context context=new Context();
        context.setVariable("id", 1L);
        context.setVariable("date", date);

        //Mock the process method of the templateEngine bean
        when(templateEngine.process("TemplateName", refEq(context))).thenReturn("Html template result");

        //Now we can test the method
        String htmlTemplate=ticketTemplatingService.buildHtmlTemplating(ticket, "TemplateName");
        assertThat(htmlTemplate).isEqualTo("Html template result");
    }
}
Run Code Online (Sandbox Code Playgroud)

在此测试类中,嘲笑的templateEngine变量返回null,然后在执行此操作时出现“ when(templateEngine.process(“ TemplateName”,refEq(context)))。thenReturn(“ H​​TML模板结果”);“

请你能帮我吗?我真的不明白为什么。

小智 5

代替

@Autowired
private TemplateEngine templateEngine;
Run Code Online (Sandbox Code Playgroud)

在您的服务中使用此界面。

import org.thymeleaf.ITemplateEngine;

@Autowired
private ITemplateEngine templateEngine;
Run Code Online (Sandbox Code Playgroud)

并在您的测试班级中使用与模拟相同的班级

@Mock
private ITemplateEngine emailTemplateEngine;

@Before
public void setup(){
    @when(emailTemplateEngine.process(eq(TEMPLATE_USER_CREATION), any(Context.class))).thenReturn(userCreationHtml);
     .
     .
     .
}
Run Code Online (Sandbox Code Playgroud)


小智 1

我在使用 Mokito 测试 thymeleaf 模板时遇到了与您相同的问题。根据我的研究,您可能想尝试:

  1. 检查你的 Thymeleaf 罐子的版本。如果您使用 spring-boot-starter-thymeleaf dependentecny,它可能仍使用 < 3.0 版本,该版本比当前稳定版本旧。

根据此链接:TemplateEngine 中的 Final 方法使得难以模拟 3.0 版本对此类问题有更好的解决方案。

如果你使用的是3.0+版本,那么PowerMock可以来救援。 如何模拟final方法请参考此链接:https://github.com/powermock/powermock/wiki/mockfinal (此链接使用EasyMock)

如果您使用的是 < 3.0 版本,到目前为止,我发现的唯一临时修复是帖子中第一个链接的最后一条评论。

祝您的研究顺利,并希望更多的人才能够回答这个问题。