Solucionado (ver solução)
Solucionado
(ver solução)
5
respostas

Spring II - Aula 7 - ProdutoControllerTest - java.lang.IllegalStateException: 'cacheResolver' is required

Pessoal fiz toda a configuração para rodar o teste do controller, porém está estourando uma exception requirindo um cacheResolver. Segue trace:

Caused by: java.lang.IllegalStateException: 'cacheResolver' is required. Either set the cache resolver to use or set the cache manager to create a default cache resolver based on it.
    at org.springframework.util.Assert.state(Assert.java:385)
    at org.springframework.cache.interceptor.CacheAspectSupport.afterPropertiesSet(CacheAspectSupport.java:169)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1627)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1564)
    ... 107 more
5 respostas

Fala Felipe, tudo bem ?

Estranho, nunca vi isso acontecendo com o teste. Consegue mandar seu código do controller, do teste e conf por aqui pra poder dar uma analisada melhor. Eu chutaria que no perfil de testes ele não está encontrando o bean. Mas melhor olhar certinho o código.

Caso você tenha como compartilhar o projeto via algum repositório, melhor ainda.

Abraço!

Eai Rafael, Pois é, já tentei mudar as versões do Spring, clean/build e nada. Estou utilizando Java 9, será que pode ter relação? Segue:

ProdutoController

package br.com.casadocodigo.loja.controllers;

import java.util.List;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import br.com.casadocodigo.loja.daos.ProdutoDAO;
import br.com.casadocodigo.loja.infra.FileSaver;
import br.com.casadocodigo.loja.models.Produto;
import br.com.casadocodigo.loja.models.TipoPreco;
import br.com.casadocodigo.loja.validation.ProdutoValidation;

@Controller
@RequestMapping("/produtos")
public class ProdutoController {

    @Autowired
    private ProdutoDAO produtoDAO;

    @Autowired
    private FileSaver fileSaver;

    @InitBinder
    public void initBinder (WebDataBinder binder) {
        binder.addValidators(new ProdutoValidation());
    }

    @RequestMapping("/form") 
    public ModelAndView form (Produto produto) {
        ModelAndView modelAndView = new ModelAndView("produtos/form");
        modelAndView.addObject("tipos",TipoPreco.values());
        System.out.println("Página para cadastrar um produto");
        return modelAndView;
    }

    @RequestMapping(method=RequestMethod.POST) 
    @CacheEvict(value="produtosHome",allEntries=true)
    public ModelAndView cadastrar (MultipartFile sumario, @Valid Produto produto, BindingResult bindingResult, RedirectAttributes redirectAttributes) {
        System.out.println(sumario.getOriginalFilename());
        if (bindingResult.hasErrors()) {
            return form(produto);
        }

        System.out.println(produto);
        String sumarioPath = fileSaver.write("arquivos-sumario", sumario);
        produto.setSumarioPath(sumarioPath);
        produtoDAO.gravar(produto);
        redirectAttributes.addFlashAttribute("sucesso", "Produto gravado com sucesso"); 
        return new ModelAndView("redirect:/produtos");                   
    }

    @RequestMapping(method=RequestMethod.GET)
    public ModelAndView listar () {
        ModelAndView modelAndView = new ModelAndView("produtos/lista");
        List<Produto> produtos = produtoDAO.listar();
        modelAndView.addObject("produtos", produtos);
        return modelAndView;
    }

    @RequestMapping("/detalhe/{id}")
    public ModelAndView detalhe (@PathVariable("id") Integer id) {
        ModelAndView modelAndView = new ModelAndView("produtos/detalhe");
        Produto produto = produtoDAO.find(id);
        modelAndView.addObject("produto", produto);
        return modelAndView;
    }
}

ProdutoControllerTest

package br.com.casadocodigo.loja.controllers;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import br.com.casadocodigo.loja.conf.AppWebConfiguration;
import br.com.casadocodigo.loja.conf.JPAConfiguration;
import br.com.casadocodigo.loja.confs.DataSourceConfigurationTest;

@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {JPAConfiguration.class, AppWebConfiguration.class, DataSourceConfigurationTest.class})
@ActiveProfiles("test")
public class ProdutoControllerTest {

    @Autowired
    private WebApplicationContext wac;

    private MockMvc mockMvc; 

    @Before
    public void setup() {
        mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
    }

    @Test
    public void deveRetornarParaHomeComOsLivros() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.get("/"))
                .andExpect(MockMvcResultMatchers.model().attributeExists("produtos")) 
                .andExpect(MockMvcResultMatchers.forwardedUrl("/WEB-INF/views/home.jsp"));
    }
}

Obrigado!

O erro vai criando efeito cascata, segue a ultima parte do trace do JUnit:

java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:91)
    at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:74)
    at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:169)
    at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:109)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:212)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:199)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:251)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:253)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:216)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:82)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:60)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:67)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:162)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'appWebConfiguration': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.cache.config.internalCacheAdvisor' defined in class path resource [org/springframework/cache/annotation/ProxyCachingConfiguration.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.cache.interceptor.BeanFactoryCacheOperationSourceAdvisor org.springframework.cache.annotation.ProxyCachingConfiguration.cacheAdvisor()] threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cacheInterceptor' defined in class path resource [org/springframework/cache/annotation/ProxyCachingConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: 'cacheResolver' is required. Either set the cache resolver to use or set the cache manager to create a default cache resolver based on it.

Fala Felipe,

Poxa não consegui visualizar uma possível causa pelos códigos que foram postados. Pra evitar ficar pedindo várias outras classes por aqui, você poderia enviar o link de algum repositorio (no Github ou afins) compartilhando o código ?

Assim da pra gente investigar melhor a causa do problema. Abraço!

solução!

Olá Rafael, Acabei conseguindo resolver. Troquei a versão de compilação para o Java 8 e funcionou!

Obrigado pela atenção. Abs.