当前位置: 首页 > 知识库问答 >
问题:

使用Mockito的SpringBoot控制器测试&jUnit5失败,因为Spring无法创建装载属性的PropertyService类的bean?

齐铭
2023-03-14

我有一个简单的Spring靴计划--

以下是项目结构-

如果我运行我的Spring Boot应用程序,它运行良好,没有任何错误。我能够通过我的rest控制器方法获取所有客户、获取单个客户、删除客户和添加客户。

<Customer>
<firstName>TestData</firstName>
<lastName>Test</lastName>
<gender>M</gender>
<date>2020-01-26T09:00:00.000+0000</date>
<authId>6AE-BH3-24F-67FG-76G-345G-AGF6H</authId>
<addressdto>
<city>Test City</city>
<country>Test Country</country>
</addressdto>
</Customer>
    null
@PostMapping("/customer")
    public ResponseEntity<String> addCustomer(@RequestBody CustomerDto customerDto) {
        String message = "";
        ResponseEntity<String> finalMessage = null;
        try {
            if ((!customerDto.getAuthId().equals(propertyService.getKeytoAddCustomer()))) {
                System.out.println("If check failed: "+propertyService.getKeytoAddCustomer());
                System.out.println("Unauthorized access attempted");
                message = "Unauthorized access attempted";
                finalMessage = new ResponseEntity<>(message, HttpStatus.UNAUTHORIZED);
            }
            System.out.println("If check passed :"+propertyService.getKeytoAddCustomer());

            Customer customer = mapper.mapToEntity(customerDto);
            customerService.addCustomer(customer);
            message = "Customer with " + customer.getId() + " sucessfully added";
            finalMessage = new ResponseEntity<>(message, HttpStatus.OK);

        } catch (Exception e) {
            message = "Failed to add customer due to " + e.getMessage();
            finalMessage = new ResponseEntity<>(message, HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return finalMessage;
    }

ps-等于(PropertyService.GetKeyToAddCustomer()))(问题1)-->这里我得到的是空指针异常

PropertyService.java

package com.spring.liquibase.demo.utility;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;

@Configuration
@PropertySource("classpath:config.properties")
public class PropertyService {
    @Autowired
    private Environment env;

    public String getKeytoAddCustomer() {
        return env.getProperty("auth.key.to.add.customer");
    }
}

HomeControllerTest.java


@ExtendWith(SpringExtension.class)
class HomeControllerTest {
    private MockMvc mvc;

    @InjectMocks
    private HomeController homeController;

    @MockBean
    private CustomerService customerService;
//
//  @Autowired
//  private PropertyService propertyService;

    @BeforeEach
    public void setup() {
        mvc = MockMvcBuilders.standaloneSetup(homeController).build();
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testaddCustomer() throws Exception {
        String uri = "/customer";
        CustomerDto custDto = this.mockCustomerObject();
        String actualResult = mvc
                .perform(MockMvcRequestBuilders.post(uri).contentType(MediaType.APPLICATION_JSON)
                        .content(asJsonString(custDto)))
                .andExpect(MockMvcResultMatchers.status().isOk()).andReturn().getResponse().getContentAsString();
        Assertions.assertEquals(actualResult, "Customer with " + custDto.getId() + " sucessfully added");
    }

    private CustomerDto mockCustomerObject() {
        CustomerDto cusDto = new CustomerDto();
        AddressDto addressDto = new AddressDto();
        addressDto.setCity("BBSR");
        addressDto.setCountry("INDIA");
        cusDto.setDate(new Date());
        cusDto.setFirstName("Biprojeet");
        cusDto.setLastName("KAR");
        cusDto.setGender("M");
        cusDto.setAuthId(" 6AE-BH3-24F-67FG-76G-345G-AGF6H");
        cusDto.setAddressdto(addressDto);
        return cusDto;

    }

    public static String asJsonString(CustomerDto cusDto) {
        try {
            return new ObjectMapper().writeValueAsString(cusDto);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
# DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
spring.datasource.url=jdbc:mysql******useSSL=false
spring.datasource.username=****
spring.datasource.password=****

# Hibernate
# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect

# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto = update
logging.level.org.springframework.web=INFO
logging.level.com=DEBUG

customer.auth.key = 6AE-BH3-24F-67FG-76G-345G-AGF6H

same as above
spring.profiles.active=dev
logging.level.org.springframework.web=INFO
logging.level.com=DEBUG
server.port=8080

java.lang.AssertionError: Status expected:<200> but was:<500>
    at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:59)
    at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:122)
    at org.springframework.test.web.servlet.result.StatusResultMatchers.lambda$matcher$9(StatusResultMatchers.java:627)
    at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:196)
    at com.spring.liquibase.demo.controller.HomeControllerTest.testaddCustomer(HomeControllerTest.java:50)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.base/java.lang.reflect.Method.invoke(Unknown Source)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:436)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:115)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:170)
    at org.junit.jupiter.engine.execution.ThrowableCollector.execute(ThrowableCollector.java:40)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:166)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:113)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:58)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(HierarchicalTestExecutor.java:112)
    at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.executeRecursively(HierarchicalTestExecutor.java:108)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.execute(HierarchicalTestExecutor.java:79)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$2(HierarchicalTestExecutor.java:120)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(Unknown Source)
    at java.base/java.util.stream.ReferencePipeline$2$1.accept(Unknown Source)
    at java.base/java.util.Iterator.forEachRemaining(Unknown Source)
    at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Unknown Source)
    at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
    at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source)
    at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source)
    at java.base/java.util.stream.ReferencePipeline.forEach(Unknown Source)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(HierarchicalTestExecutor.java:120)
    at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.executeRecursively(HierarchicalTestExecutor.java:108)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.execute(HierarchicalTestExecutor.java:79)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$2(HierarchicalTestExecutor.java:120)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(Unknown Source)
    at java.base/java.util.stream.ReferencePipeline$2$1.accept(Unknown Source)
    at java.base/java.util.Iterator.forEachRemaining(Unknown Source)
    at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Unknown Source)
    at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
    at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source)
    at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source)
    at java.base/java.util.stream.ReferencePipeline.forEach(Unknown Source)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(HierarchicalTestExecutor.java:120)
    at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.executeRecursively(HierarchicalTestExecutor.java:108)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.execute(HierarchicalTestExecutor.java:79)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:55)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:43)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:170)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:154)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:90)
    at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:89)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)

共有1个答案

淳于乐池
2023-03-14

在完成你的回购之后,这里是最终的代码

@WebMvcTest(HomeController.class)
class HomeControllerTest {

@Autowired
private MockMvc mvc;

@MockBean
private CustomerService customerService;

@MockBean
private PropertyService propertyService;

@MockBean
private EntityToDtoMapper mapper;


@Test
public void testaddCustomer() throws Exception {
    String uri = "/customer";
    CustomerDto custDto = this.mockCustomerObject();
    Customer customer = getCustomerEntity();
    Mockito.when(mapper.mapToEntity(Mockito.any(CustomerDto.class))).thenReturn(customer);
    String actualResult = mvc
            .perform(MockMvcRequestBuilders.post(uri).contentType(MediaType.APPLICATION_JSON)
                    .content(asJsonString(custDto)))
            .andExpect(MockMvcResultMatchers.status().isOk()).andReturn().getResponse().getContentAsString();
    Assertions.assertEquals(actualResult, "Customer with " + custDto.getId() + " sucessfully added");
}

private CustomerDto mockCustomerObject() {
    CustomerDto cusDto = new CustomerDto();
    AddressDto addressDto = new AddressDto();
    addressDto.setCity("BBSR");
    addressDto.setCountry("INDIA");
    cusDto.setDate(new Date());
    cusDto.setFirstName("Biprojeet");
    cusDto.setLastName("KAR");
    cusDto.setGender("M");
    cusDto.setAuthId(" 6AE-BH3-24F-67FG-76G-345G-AGF6H");
    cusDto.setAddressdto(addressDto);
    return cusDto;

}


private Customer getCustomerEntity() {
    Customer customer = new Customer();
    Address address = new Address();
    address.setCity("BBSR");
    address.setCountry("INDIA");
    customer.setDate(new Date());
    customer.setFirstName("Biprojeet");
    customer.setLastName("KAR");
    customer.setGender("M");
    customer.setAddress(address);
    return customer;

}

public static String asJsonString(CustomerDto cusDto) {
    try {
        return new ObjectMapper().writeValueAsString(cusDto);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

}

这里的问题是你把这些概念混合在一起。在您的实现中,您试图进行单元测试,但期望集成的行为。

因为我们已经为控制器上传了spring应用程序上下文,所以控制器也需要应用程序上下文中的bean,这可以通过@mockbean注释来实现。

在模拟所有这些bean之后,将创建您的控制器bean,但有些方法需要一些返回值,因此您必须在代码中编写预期的返回值,可以这样做

Mockito.when(mapper.mapToEntity(Mockito.any(CustomerDto.class))).thenReturn(customer);

如果您错过了这一特定步骤,那么在控制器中,您将在这一行代码中得到一个空指针异常

message = "Customer with " + customer.getId() + " sucessfully added";
Customer customer = mapper.mapToEntity(customerDto);
 类似资料:
  • 我有一个Spring Boot应用程序,想为控制器编写集成测试。它是我的: 它是我的控制器: 我创建了一个测试(JUnit5): 哪种方法更好?

  • 我正在尝试为springboot应用程序中的一个简单控制器编写一个测试。但是,由于为我的TopicRepository和topiccontroller创建bean而收到错误。我参考了一个教程,对spring boot开发并不陌生,所以不确定它是如何工作的。我怎样才能使测试工作? 控制器测试 控制器 专题存储库 我得到的错误是 UnsatisfiedDependencyException:创建名为'

  • 我有一个工作控制器,用于在发布请求中上传csv。邮递员状态200,测试时状态400。我正在努力看看问题是什么。 控制器: CsvHelper Util: 测试: 当测试失败时,我可以看到这个已解决的异常:类型=org.springframework.web.multipart.support.MissingServletRequest estPartException

  • 我试图用JUnit5控制台启动器运行一个简单的测试。我试了几个选择,但都不起作用。谁能告诉我哪里出了问题吗? .+--JUnit Jupiter[OK] '--JUnit Vintage[OK] 测试运行在11毫秒后完成[2个容器] [0个容器跳过][2个容器启动] [0个容器中止][2个容器成功] [0个容器失败][0个测试找到] [0个测试跳过][0个测试启动] [0个测试中止][0个测试成功

  • 问题内容: 我正在尝试使用JUnit5控制台启动器运行一个简单的测试。我尝试了几种选择,但是没有用。有人可以告诉我哪里出了问题吗? 给我警告 我试图在目录中运行所有测试,但这似乎找不到测试: 结果是这样的: 。+-JUnit Jupiter [确定] ‘-JUnit Vintage [确定] 11毫秒后测试运行完成[找到2个容器] [跳过0个容器] [0个容器中止] [2个容器成功] [0个容器失

  • Maven Pom: 更新/更正 更正:UserControllerTest.java中的已更正为,这对于junit 5是正确的。