java @Mock导致异常,但@MockBean在Spring Boot 应用程序中有效

ix0qys7i  于 2023-01-19  发布在  Java
关注(0)|答案(1)|浏览(360)

我正在学习如何在一个spring Boot 应用程序中为控制器层编写测试用例。我已经使用@Mock模拟了服务层测试用例中的存储库接口,并且它工作/编译了,测试用例得到了执行。在控制器层测试用例中,@Mock导致异常,但@MockBean工作正常。
我试图从其他资源中了解@Mock和@MockBean之间的区别,但希望更清楚地了解为什么@Mock在服务测试中有效,但在控制器测试中无效。
请参考我的代码-
1.实体

package com.learning.microservices.userservice.model;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "Consumer")
public class Consumer {
    @Id
    private Long consumerId;
    private String consumerName;
    private String emailAddress;
}

1.储存库

package com.learning.microservices.userservice.repository;

import com.learning.microservices.userservice.model.Consumer;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface ConsumerRepository extends MongoRepository<Consumer, Long> {
}

1.服务
1.接口

package com.learning.microservices.userservice.Service;

import com.learning.microservices.userservice.model.Consumer;

public interface ConsumerService {
    public Consumer saveConsumer(Consumer consumer);
}

1.执行情况

package com.learning.microservices.userservice.Service;

import com.learning.microservices.userservice.model.Consumer;
import com.learning.microservices.userservice.repository.ConsumerRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class ConsumerServiceImpl implements ConsumerService {
    @Autowired
    ConsumerRepository consumerRepository;

    public Consumer saveConsumer(Consumer consumer){
        if (consumerRepository.findById(consumer.getConsumerId()).isPresent())
            throw new RuntimeException("Consumer already exists");//should return 409
        return consumerRepository.save(consumer);
    }
}

1.主计长

package com.learning.microservices.userservice.controller;

import com.learning.microservices.userservice.Service.ConsumerService;
import com.learning.microservices.userservice.model.Consumer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import java.net.URI;

@RestController
@RequestMapping("/consumers")
public class ConsumerController {

    @Autowired
    ConsumerService consumerService;

    @PostMapping
    public ResponseEntity<Consumer> saveConsumer(@RequestBody Consumer consumer) {
        Consumer savedConsumer = consumerService.saveConsumer(consumer);
        URI consumerLocation = ServletUriComponentsBuilder.fromCurrentRequest().path("/{consumerId}").buildAndExpand(savedConsumer.getConsumerId()).toUri();
        return ResponseEntity.created(consumerLocation).build();
    }

}

1.测试用例
1.服务

package com.learning.microservices.userservice.Service;

import com.learning.microservices.userservice.model.Consumer;
import com.learning.microservices.userservice.repository.ConsumerRepository;
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.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.util.Optional;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;

@ExtendWith(MockitoExtension.class)
class ConsumerServiceImplTest {

    @Mock
    private ConsumerRepository consumerRepository;

    @InjectMocks
    private ConsumerServiceImpl consumerService;

    private Consumer consumer;

    @BeforeEach
    public void setUp() {
        consumer = Consumer.builder()
                .consumerId(1L)
                .consumerName("Test Consumer")
                .emailAddress("test.consumer@test.com")
                .build();
    }

    @AfterEach
    public void tearDown() {
        consumer = null;
    }
    @Test
    void saveConsumer() {
        given(consumerRepository.findById(consumer.getConsumerId())).willReturn(Optional.empty());
        given(consumerService.saveConsumer(consumer)).willReturn(consumer);
        Consumer savedConsumer = consumerService.saveConsumer(consumer);
        assertThat(savedConsumer).isNotNull();
    }

}

1.主计长

package com.learning.microservices.userservice.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.learning.microservices.userservice.Service.ConsumerServiceImpl;
import com.learning.microservices.userservice.model.Consumer;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;

import java.nio.charset.StandardCharsets;

import static org.mockito.BDDMockito.given;

@WebMvcTest
class ConsumerControllerTest {

    private ObjectMapper objectMapper;
    private Consumer consumer;

    @Autowired
    private MockMvc mockMvc;

    @Mock
    private ConsumerServiceImpl consumerService;

    @InjectMocks
    private ConsumerController consumerController;

    @BeforeEach
    public void setUp() {
        consumer = Consumer.builder()
                .consumerId(1L)
                .consumerName("Test Consumer")
                .emailAddress("test.consumer@test.com")
                .build();
        objectMapper = new ObjectMapper();
    }

    @AfterEach
    public void tearDown() {
        consumer = null;
        objectMapper = null;
    }

    @Test
    void saveConsumer() throws Exception {
        given(consumerService.saveConsumer(consumer)).willReturn(consumer);
        mockMvc.perform(MockMvcRequestBuilders.post("/consumers")
                .contentType(MediaType.APPLICATION_JSON)
                .content(objectMapper.writeValueAsString(consumer))
                .characterEncoding(StandardCharsets.UTF_8)
        )
        .andExpect(MockMvcResultMatchers.status().isCreated());
    }
}

1.异常日志

java.lang.IllegalStateException: Failed to load ApplicationContext for [WebMergedContextConfiguration@5f8a02cf testClass = com.learning.microservices.userservice.controller.ConsumerControllerTest, locations = [], classes = [com.learning.microservices.userservice.UserServiceApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceLocations = [], propertySourceProperties = ["org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTestContextBootstrapper=true"], contextCustomizers = [[ImportsContextCustomizer@26d5a317 key = [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration, org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration, org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration, org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration, org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration, org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration, org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration, org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration, org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration, org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration, org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration, org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration, org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration, org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration, org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration, org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcAutoConfiguration, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcWebClientAutoConfiguration, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcWebDriverAutoConfiguration, org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration, org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration, org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration, org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration, org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcSecurityConfiguration, org.springframework.boot.test.autoconfigure.web.reactive.WebTestClientAutoConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@2034b64c, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@7161d8d1, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer@d737b89, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@9da1, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer@234914f5, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@e322556a, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@2ab4bc72, org.springframework.boot.test.context.SpringBootTestAnnotation@4ddbcfe0], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]

  at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:142)
  at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:127)
  at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:141)
  at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:97)
  at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:241)
  at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:138)
  at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$10(ClassBasedTestDescriptor.java:377)
  at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:382)
  at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$11(ClassBasedTestDescriptor.java:377)
  at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
  at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
  at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
  at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
  at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
  at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310)
  at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
  at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734)
  at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
  at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestInstancePostProcessors(ClassBasedTestDescriptor.java:376)
  at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$instantiateAndPostProcessTestInstance$6(ClassBasedTestDescriptor.java:289)
  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
  at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:288)
  at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$4(ClassBasedTestDescriptor.java:278)
  at java.base/java.util.Optional.orElseGet(Optional.java:364)
  at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$5(ClassBasedTestDescriptor.java:277)
  at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:31)
  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:105)
  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:104)
  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:68)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$2(NodeTestTask.java:123)
  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:123)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:90)
  at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
  at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
  at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
  at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
  at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
  at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
  at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
  at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
  at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
  at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:147)
  at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:127)
  at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:90)
  at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:55)
  at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:102)
  at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:54)
  at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
  at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
  at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
  at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
  at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:57)
  at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
  at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
  at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
  at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
  at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'consumerController': Unsatisfied dependency expressed through field 'consumerService': No qualifying bean of type 'com.learning.microservices.userservice.Service.ConsumerService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
  at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:712)
  at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:692)
  at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:127)
  at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:481)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1397)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:598)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521)
  at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326)
  at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
  at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324)
  at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
  at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:961)
  at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:915)
  at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:584)
  at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730)
  at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:432)
  at org.springframework.boot.SpringApplication.run(SpringApplication.java:308)
  at org.springframework.boot.test.context.SpringBootContextLoader.lambda$loadContext$3(SpringBootContextLoader.java:137)
  at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:59)
  at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:47)
  at org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1386)
  at org.springframework.boot.test.context.SpringBootContextLoader$ContextLoaderHook.run(SpringBootContextLoader.java:543)
  at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:137)
  at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:108)
  at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:184)
  at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:118)
  ... 72 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.learning.microservices.userservice.Service.ConsumerService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
  at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1812)
  at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1371)
  at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1325)
  at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:709)
  ... 97 more
taor4pac

taor4pac1#

@Mock@MockBean之间的区别仅仅是@MockBean注解了一个对象,该对象被注入到Spring上下文中并在测试中用作bean,并且也是一个mock。@MockBean扩展了@Mock的功能,而@Mock与Spring框架无关。
Service的测试与Spring没有任何关系--您可以简单地通过查看类的导入来验证这一点。没有来自org.springframework包的单个导入。在这里使用@Mock本身是非常好的。MockitoExtension@InjectMocks的组合负责模拟的生命周期。创建模拟示例并注入测试主题(consumerService),但不创建Spring上下文。
Controller测试中,您使用的是与Spring相关的类,尤其是MockMvc@WebMvcTest--由于后者,前者会自动注入,@WebMvcTest会设置Spring上下文以进行Web层处理。由于MockMvc上执行的请求可以访问端点。这里的重要部分是其他组件(层)不会被自动扫描和注入。这就是错误状态的原因:
创建名为"consumerController"的Bean时出错:未满足的依赖关系(...)
Spring尝试创建控制器bean,但是找不到服务bean。@MockBean通知Spring应该创建模拟并将其作为bean使用。这就是为什么使用此注解的测试可以工作的原因-可以正确创建Spring上下文,可以注入bean。其中一些(服务)作为模拟。
有关详细信息,请参阅以下内容中的说明和示例:Testing the Web Layer in Spring docs.
此外,您还可以在这里找到一个使用@TestConfiguration以编程方式创建的spy bean示例。这类似于使用@SpyBean注解,但在一些更复杂的情况下可能会有所帮助,因此值得在这里注意。@TestConfigurationmock的工作方式与@MockBean类似,这使得Spring测试配置更容易。

相关问题