164 votes

Comment éviter l'exception " Circular view path " avec le test Spring MVC

J'ai le code suivant dans un de mes contrôleurs :

@Controller
@RequestMapping("/preference")
public class PreferenceController {

    @RequestMapping(method = RequestMethod.GET, produces = "text/html")
    public String preference() {
        return "preference";
    }
}

J'essaie simplement de le tester en utilisant Test de Spring MVC comme suit :

@ContextConfiguration
@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class PreferenceControllerTest {

    @Autowired
    private WebApplicationContext ctx;

    private MockMvc mockMvc;
    @Before
    public void setup() {
        mockMvc = webAppContextSetup(ctx).build();
    }

    @Test
    public void circularViewPathIssue() throws Exception {
        mockMvc.perform(get("/preference"))
               .andDo(print());
    }
}

J'obtiens l'exception suivante :

Chemin d'accès circulaire [préférence] : renvoie à l'URL du gestionnaire actuel [/préférence]. gestionnaire actuel [/préférence]. Vérifiez la configuration de votre ViewResolver ! (Indice : Cela peut être le résultat d'une vue non spécifiée, en raison de la vue par défaut. par défaut).

Ce que je trouve étrange, c'est que cela fonctionne bien lorsque je charge la configuration contextuelle "complète". qui inclut le modèle et les résolveurs de vue comme indiqué ci-dessous :

<bean class="org.thymeleaf.templateresolver.ServletContextTemplateResolver" id="webTemplateResolver">
    <property name="prefix" value="WEB-INF/web-templates/" />
    <property name="suffix" value=".html" />
    <property name="templateMode" value="HTML5" />
    <property name="characterEncoding" value="UTF-8" />
    <property name="order" value="2" />
    <property name="cacheable" value="false" />
</bean>

Je suis bien conscient que le préfixe ajouté par le résolveur de modèle garantit qu'il n'y a pas de "chemin de vue circulaire" lorsque l'application utilise ce résolveur de modèle.

Mais alors comment suis-je censé tester mon application en utilisant le test Spring MVC ?

16voto

Anon Points 480

Voici une solution facile si vous ne vous souciez pas vraiment du rendu de la vue.

Créez une sous-classe de InternalResourceViewResolver qui ne vérifie pas les chemins de vue circulaires :

public class StandaloneMvcTestViewResolver extends InternalResourceViewResolver {

    public StandaloneMvcTestViewResolver() {
        super();
    }

    @Override
    protected AbstractUrlBasedView buildView(final String viewName) throws Exception {
        final InternalResourceView view = (InternalResourceView) super.buildView(viewName);
        // prevent checking for circular view paths
        view.setPreventDispatchLoop(false);
        return view;
    }
}

Puis mettez en place votre test avec :

MockMvc mockMvc;

@Before
public void setUp() {
    final MyController controller = new MyController();

    mockMvc =
            MockMvcBuilders.standaloneSetup(controller)
                    .setViewResolvers(new StandaloneMvcTestViewResolver())
                    .build();
}

15voto

Si vous utilisez Spring Boot, ajoutez la dépendance thymeleaf dans votre pom.xml :

    <dependency>
        <groupId>org.thymeleaf</groupId>
        <artifactId>thymeleaf-spring4</artifactId>
        <version>2.1.6.RELEASE</version>
    </dependency>

13voto

Ajout de / après /preference a résolu le problème pour moi :

@Test
public void circularViewPathIssue() throws Exception {
    mockMvc.perform(get("/preference/"))
           .andDo(print());
}

13voto

MozenRath Points 1190

Si vous n'avez pas utilisé un @RequestBody et n'utilisent que @Controller La manière la plus simple de résoudre ce problème est d'utiliser @RestController au lieu de @Controller

8voto

johnmilimo Points 81

Dans mon cas, j'essayais Kotlin + Spring boot et j'ai rencontré le problème du Circular View Path. Toutes les suggestions que j'ai obtenues en ligne n'ont pas pu m'aider, jusqu'à ce que j'essaie la solution ci-dessous :

À l'origine, j'avais annoté mon contrôleur à l'aide des éléments suivants @Controller

import org.springframework.stereotype.Controller

J'ai ensuite remplacé @Controller avec @RestController

import org.springframework.web.bind.annotation.RestController

Et ça a marché.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X