尝试模拟时出现java.lang.ExceptionInInitializerError

时间:2020-10-28 20:23:50

标签: java unit-testing mockito spring-mvc-test junit-jupiter

尝试模拟接口org.springframework.ui.Model的对象时遇到了这个问题。我正在使用带有Java 8和JUnit Jupiter的Mockito 3.5.15。我尝试在全局和方法内部同时使用@MockMockito.mock(),但是无论如何都会出现错误。由于initMocks()已过时,因此我正在使用Mockito.openMocks()。我知道testGetMenu()的内容并不会引起错误,因为即使方法主体为空,我也会得到它。被测试的类是Spring MVC控制器。

模拟时的堆栈跟踪:

java.lang.ExceptionInInitializerError
    at org.mockito.internal.exceptions.stacktrace.ConditionalStackTraceFilter.<init>(ConditionalStackTraceFilter.java:17)
    at org.mockito.exceptions.base.MockitoException.filterStackTrace(MockitoException.java:41)
    at org.mockito.exceptions.base.MockitoException.<init>(MockitoException.java:30)
    at org.mockito.exceptions.misusing.MockitoConfigurationException.<init>(MockitoConfigurationException.java:18)
    at org.mockito.internal.configuration.plugins.PluginLoader.loadImpl(PluginLoader.java:66)
    at org.mockito.internal.configuration.plugins.PluginLoader.loadPlugin(PluginLoader.java:24)
    at org.mockito.internal.configuration.plugins.PluginRegistry.<init>(PluginRegistry.java:12)
    at org.mockito.internal.configuration.plugins.Plugins.<clinit>(Plugins.java:11)
    at org.mockito.internal.util.MockUtil.<clinit>(MockUtil.java:24)
    at org.mockito.internal.stubbing.defaultanswers.ReturnsEmptyValues.<init>(ReturnsEmptyValues.java:58)
    at org.mockito.internal.stubbing.defaultanswers.ReturnsMoreEmptyValues.<init>(ReturnsMoreEmptyValues.java:51)
    at org.mockito.internal.stubbing.defaultanswers.ReturnsSmartNulls.<init>(ReturnsSmartNulls.java:40)
    at org.mockito.Answers.<clinit>(Answers.java:43)
    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 java.lang.Class.getEnumConstantsShared(Class.java:3320)
    at java.lang.Class.enumConstantDirectory(Class.java:3341)
    at java.lang.Enum.valueOf(Enum.java:232)
    at sun.reflect.annotation.AnnotationParser.parseEnumValue(AnnotationParser.java:483)
    at sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:347)
    at java.lang.reflect.Method.getDefaultValue(Method.java:606)
    at sun.reflect.annotation.AnnotationType.<init>(AnnotationType.java:132)
    at sun.reflect.annotation.AnnotationType.getInstance(AnnotationType.java:85)
    at sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:266)
    at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120)
    at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:72)
    at java.lang.reflect.Field.declaredAnnotations(Field.java:1150)
    at java.lang.reflect.Field.declaredAnnotations(Field.java:1148)
    at java.lang.reflect.Field.getAnnotation(Field.java:1120)
    at java.lang.reflect.AccessibleObject.getDeclaredAnnotation(AccessibleObject.java:219)
    at org.junit.platform.commons.util.AnnotationUtils.findAnnotation(AnnotationUtils.java:128)
    at org.junit.platform.commons.util.AnnotationUtils.findAnnotation(AnnotationUtils.java:115)
    at org.junit.platform.commons.util.AnnotationUtils.isAnnotated(AnnotationUtils.java:93)
    at org.junit.platform.commons.util.AnnotationUtils.lambda$findAnnotatedFields$6(AnnotationUtils.java:369)
    at java.util.function.Predicate.lambda$and$0(Predicate.java:69)
    at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:174)
    at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
    at org.junit.platform.commons.util.ReflectionUtils.findFields(ReflectionUtils.java:1137)
    at org.junit.platform.commons.util.AnnotationUtils.findAnnotatedFields(AnnotationUtils.java:371)
    at org.junit.platform.commons.util.AnnotationUtils.findAnnotatedFields(AnnotationUtils.java:348)
    at org.junit.jupiter.engine.descriptor.ExtensionUtils.registerExtensionsFromFields(ExtensionUtils.java:99)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.prepare(ClassBasedTestDescriptor.java:148)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.prepare(ClassBasedTestDescriptor.java:78)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$1(NodeTestTask.java:107)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:107)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:75)
    at java.util.ArrayList.forEach(ArrayList.java:1257)
    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:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
    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:248)
    at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$5(DefaultLauncher.java:211)
    at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:226)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:199)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:141)
    at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:98)
    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)
Caused by: java.lang.NullPointerException
    at org.mockito.internal.configuration.plugins.Plugins.getStackTraceCleanerProvider(Plugins.java:17)
    at org.mockito.internal.exceptions.stacktrace.StackTraceFilter.<clinit>(StackTraceFilter.java:21)
    ... 78 more

AppControllerTest.java

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.ui.Model;

import com.javaduckspizza.OnlineOrderingApplication.common.TypesCache;
import com.javaduckspizza.OnlineOrderingApplication.main.AppController;

@ExtendWith(MockitoExtension.class)
@RunWith(MockitoJUnitRunner.class)
class AppControllerTest {
    @InjectMocks
    AppController appController = new AppController();
    @Mock
    Model model;

    @BeforeEach
    void setUp() throws Exception {
//      model = Mockito.mock(Model.class);
        MockitoAnnotations.openMocks(this); //using because initMocks() is deprecated
    }

    @AfterEach
    void tearDown() throws Exception {
    }

    @Test
    void testGetMenu() {
        String result = appController.getMenu(model);
        assertEquals(result, "/menu.");
        verify(model, times(5)).addAttribute(Mockito.anyString(), Mockito.any());
        verify(model, times(1)).addAttribute(Mockito.anyString(), Mockito.anyInt());
        MockedStatic<TypesCache> mockedTypesCache = Mockito.mockStatic(TypesCache.class);
        mockedTypesCache.verify(Mockito.times(5), () -> TypesCache.getActiveTypesByCategory(Mockito.anyString()));
    }
}

AppController.java

import java.math.BigDecimal;
import java.util.Date;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.ws.rs.GET;
import javax.ws.rs.POST;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.javaduckspizza.OnlineOrderingApplication.common.TypesCache;
import com.javaduckspizza.service.dao.ModifierServiceDao;
import com.javaduckspizza.service.dao.OrderServiceDao;
import com.javaduckspizza.vo.ModifierVo;
import com.javaduckspizza.vo.OrdersVo;
import com.javaduckspizza.vo.PizzaToppingAssociationVo;
import com.javaduckspizza.vo.PizzaVo;

@Controller
@RequestMapping("/")
public class AppController {
    protected Map<PizzaVo, List<PizzaToppingAssociationVo>> mapShoppingCart =
            new HashMap<PizzaVo, List<PizzaToppingAssociationVo>>();

    @GET
    @RequestMapping("/menu")
    public String getMenu(Model model) {
        System.err.println("In AppController.getMenu()");
        addAttributesForMenu(model);
        model.addAttribute("itemCount", mapShoppingCart.size());

        return "/menu.";  //I probably messed up something in the configuration.  If written without / and ., it tries to get WEB-INF/jspmenujsp
    }

    public void addAttributesForMenu(Model model) {
        model.addAttribute("sizes", TypesCache.getActiveTypesByCategory("SIZE"));
        model.addAttribute("crusts", TypesCache.getActiveTypesByCategory("CRST"));
        model.addAttribute("cheeses", TypesCache.getActiveTypesByCategory("CHES"));
        model.addAttribute("sauces", TypesCache.getActiveTypesByCategory("SAUC"));
        model.addAttribute("toppings", TypesCache.getActiveTypesByCategory("TOPP"));
    }
}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.javaduckspizza</groupId>
    <artifactId>OnlineOrderingApplication</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>OnlineOrderingApplication</name>
    <description>Online ordering application for Java Ducks Pizza</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>3.5.15</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-inline</artifactId>
            <version>3.5.15</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-junit-jupiter</artifactId>
            <version>3.5.15</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>jakarta.ws.rs</groupId>
            <artifactId>jakarta.ws.rs-api</artifactId>
            <version>2.1.6</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.7.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>5.7.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.2</version>
            </plugin>
        </plugins>
    </build>
</project>

我不嘲笑的堆栈跟踪

java.lang.NoSuchMethodError: org.mockito.Mockito.mockitoSession()Lorg/mockito/session/MockitoSessionBuilder;
    at org.mockito.junit.jupiter.MockitoExtension.beforeEach(MockitoExtension.java:149)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeBeforeEachCallbacks$1(TestMethodTestDescriptor.java:154)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeBeforeMethodsOrCallbacksUntilExceptionOccurs$5(TestMethodTestDescriptor.java:190)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeBeforeMethodsOrCallbacksUntilExceptionOccurs(TestMethodTestDescriptor.java:190)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeBeforeEachCallbacks(TestMethodTestDescriptor.java:153)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:131)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:71)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
    at java.util.ArrayList.forEach(ArrayList.java:1257)
    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:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
    at java.util.ArrayList.forEach(ArrayList.java:1257)
    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:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
    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:248)
    at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$5(DefaultLauncher.java:211)
    at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:226)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:199)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:141)
    at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:98)
    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)
    Suppressed: java.lang.NullPointerException
        at org.mockito.junit.jupiter.MockitoExtension.afterEach(MockitoExtension.java:184)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAfterEachCallbacks$11(TestMethodTestDescriptor.java:248)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAllAfterMethodsOrCallbacks$13(TestMethodTestDescriptor.java:268)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAllAfterMethodsOrCallbacks$14(TestMethodTestDescriptor.java:268)
        at java.util.ArrayList.forEach(ArrayList.java:1257)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeAllAfterMethodsOrCallbacks(TestMethodTestDescriptor.java:267)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeAfterEachCallbacks(TestMethodTestDescriptor.java:247)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:143)
        ... 43 more

2 个答案:

答案 0 :(得分:0)

您要测试的用例不是@InjectMocks@Mock结合使用的目的。每当您要模拟被测类的协作者时,都可以使用此设置。

假设您的AppController将注入(例如通过构造函数)UserService以获取数据。对于这种情况,您可以将@Mock用于UserService,并在AppController的整个单元测试中模拟该服务的行为。

Model不是您的AppController的合作者,而是Spring注入您的方法的人。

在您的测试方案中,模拟Model没有多大意义。宁可使用@WebMvcTest启动切片的Spring Context,然后使用MockMvc访问您的端点。然后,您可以使用MockMvc的验证方法来检查Model,视图名称和响应代码。

一个示例如下所示:

@WebMvcTest(DashboardController.class)
class DashboardControllerTest {
 
  @Autowired
  private MockMvc mockMvc;
 
  @MockBean
  private DashboardService dashboardService;
 
  @Test
  public void shouldReturnViewWithPrefilledData() throws Exception {
    when(dashboardService.getAnalyticsGraphData()).thenReturn(new Integer[]{13, 42});
 
    this.mockMvc
      .perform(get("/dashboard"))
      .andExpect(status().isOk())
      .andExpect(view().name("dashboard"))
      .andExpect(model().attribute("user", "Duke"))
      .andExpect(model().attribute("analyticsGraph", Matchers.arrayContaining(13, 42)))
      .andExpect(model().attributeExists("quickNote"));
  }
}

您可以在此MockMvc guide中找到更多信息。

PS:@RunWith(MockitoRunner.class)用于JUnit 4,如果使用JUnit Jupiter,则可以将其删除。

答案 1 :(得分:0)

我在上面的评论中引用的代码:

AppControllerTest.java


    @Test
    void testAddItem_Attributes() {
        Long crust = Long.valueOf(0L);
        Long sauce = Long.valueOf(1L);
        Long size = Long.valueOf(2L);
        Long cheese = Long.valueOf(3L);

        PizzaToppingAssociationVo ptavBothSides = new PizzaToppingAssociationVo();
        PizzaToppingAssociationVo ptavLeftOnly = new PizzaToppingAssociationVo();
        PizzaToppingAssociationVo ptavRightOnly = new PizzaToppingAssociationVo();

        ptavBothSides.setLeft(true);
        ptavBothSides.setRight(true);
        ptavBothSides.setToppingsId(5L);

        ptavLeftOnly.setLeft(true);
        ptavLeftOnly.setRight(false);
        ptavLeftOnly.setToppingsId(6L);

        ptavRightOnly.setLeft(false);
        ptavRightOnly.setRight(true);
        ptavRightOnly.setToppingsId(8L);

        PizzaToppingAssociationVo [] toppingsArray = {ptavBothSides, ptavLeftOnly, ptavRightOnly};

        try {
            ObjectMapper objectMapper = new ObjectMapper();
            String jsonToppings = objectMapper.writeValueAsString(toppingsArray);
            
            //this line throws the IllegalStateException with these parameters, but not if called with only "/addItem"
            ResultActions ra = mockMvc.perform(MockMvcRequestBuilders.post("/addItem", crust, sauce, size, cheese, jsonToppings));
            ra.andExpect(MockMvcResultMatchers.status().is3xxRedirection());
            ra.andExpect(MockMvcResultMatchers.redirectedUrl("/menu"));
            ra.andExpect(model().attribute("crust", crust));

            Map<String, Object> modelMap = ra.andReturn().getModelAndView().getModel();
            assertEquals(modelMap.size(), 1);
            assert(modelMap.containsKey("itemCount"));
        } catch (Exception e) {
            e.printStackTrace();
            fail();
        }
    }