Tes SpringBoot Controller menggunakan Mockito & jUnit5 gagal karena Spring tidak dapat membuat kacang kelas PropertyService yang memuat properti?

Saya punya proyek boot musim semi sederhana--

Berikut adalah struktur proyek-

masukkan deskripsi gambar di sini

Jika saya menjalankan aplikasi spring boot saya, itu berjalan dengan baik tanpa kesalahan apa pun. Saya bisa mendapatkan semua pelanggan, mendapatkan satu pelanggan, menghapus satu pelanggan, dan menambahkan pelanggan melalui metode pengontrol lainnya.

Melalui Postman saya dapat menambahkan pelanggan--

<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>

Respon

Customer with 34 sucessfully added

Ini berarti ketika aplikasi aktif, ia dapat membuat instance PropertyService.java. jadi saya dapat mengakses id otentikasi yang ada di application-dev.properties hingga PropertyService.java saya. Properti yang sama ada di src/test/resources-> application.properties saya.

Ada dua masalah--

  1. Sekarang ketika saya menjalankan HomeControllerTest.java class asjUnit test saya, saya mendapatkan kesalahan. Saya melakukan debug dan menemukan akar penyebab kesalahan tersebut. Di dalam kelas HomeController.java saya, ia tidak dapat membuat instance kelas PropertyService.java, jadi saya mendapatkan null pointer exception di sana. Oleh karena itu, eksekusi kelas pengujian selanjutnya gagal.
  2. Saya tidak dapat mengakses authId melalui PropertyService.java di kelas pengujian saya, jadi saya harus melakukan hardcode.

Adakah yang bisa memberi tahu saya mengapa saya mengalami masalah ini? Dan bagaimana cara memperbaikinya?

HomeController.java

@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- equals(propertyService.getKeytoAddCustomer())) (Masalah 1) --> di sini saya mendapatkan null pointer exception

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);
        }
    }
}

PS- Saya telah mengomentari kodenya karena saya tidak dapat mengakses file prop di sini. Butuh bantuan di sini juga (Masalah 2)

application.properties-- di dalam src/test/resources

# 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

properti-aplikasi

same as above

aplikasi.properti di dalam->src/main/resources

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

Log Kesalahan jUnit

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)


person Arpan Banerjee    schedule 12.05.2020    source sumber


Jawaban (3)


Setelah melalui repo Anda, inilah kode terakhir

@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);
    }
}

}

Masalahnya di sini adalah Anda mencampurkan konsep. Dalam implementasi Anda, Anda mencoba melakukan pengujian unit tetapi mengharapkan perilaku integrasi.

Saat Anda menggunakan boot Spring dengan starter kit pengujiannya yang dilengkapi dengan dependensi kerangka kerja seperti JUnit dan Mockito, Anda dapat dengan mudah meniru kelas dan metode tersebut yang memunculkan pengecualian penunjuk Null dengan menggunakan kerangka mockitio karena server tidak berjalan dan wadah IOC sedang berjalan. tidak sampai itu sebabnya itu NULL.

Jadi dalam kode Anda CustomerService, PropertyService dan EntityToDtoMapper adalah NULL.

Jadi pertanyaannya di sini adalah bagaimana kita dapat mengunggah konteks aplikasi pegas tanpa memulai server.

Hal ini dapat dilakukan dengan dua cara, yaitu memuat seluruh konteks aplikasi pegas dengan menggunakan anotasi @SpringBootTest dan @AutoConfigureMockMvc.

Atau kita dapat mempersempit konteks aplikasi pegas hanya untuk pengontrol itu sendiri dengan menggunakan anotasi @WebMvcTest

Jadi solusi yang saya gunakan di sini adalah mempersempit pengujian ke pengontrol hanya dengan menggunakan anotasi @WebMvcTest(HomeController.class).

Namun CustomerService, PropertyService, dan EntityToDtoMapper tersebut tetap NULL. Jadi untuk mengejek kelas-kelas tersebut Kita dapat menggunakan anotasi @Mock atau @MockBean, tetapi ada sedikit perbedaan antara anotasi tersebut

Metode Mockito.mock() memungkinkan kita membuat objek tiruan dari suatu kelas atau antarmuka dan @MockBean untuk menambahkan objek tiruan ke konteks aplikasi Spring. Tiruan tersebut akan menggantikan kacang yang sudah ada dengan tipe yang sama dalam konteks aplikasi.

Jadi karena kami telah mengunggah konteks aplikasi pegas untuk pengontrol, maka pengontrol juga mengharapkan kacang tersebut dalam konteks aplikasi, yang dapat dicapai dengan anotasi @MockBean.

Setelah mengejek semua kacang itu, kacang pengontrol Anda akan dibuat tetapi ada metode di mana Anda mengharapkan beberapa nilai pengembalian sehingga Anda harus mengkodekan nilai pengembalian yang diharapkan dalam kode Anda yang dapat dilakukan seperti itu

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

jika Anda melewatkan langkah khusus ini maka di pengontrol Anda akan mendapatkan pengecualian penunjuk NULL pada baris kode ini

message = "Customer with " + customer.getId() + " sucessfully added";

Karena Anda membuat kode

Customer customer = mapper.mapToEntity(customerDto);

akan mengembalikan NULL.

Saya harap ini akan membantu dan memotivasi Anda untuk mendapatkan lebih banyak pengetahuan tentang konsep-konsep tersebut.

Tolong beri tahu saya jika diperlukan bantuan lebih lanjut

person Anurag Srivastava    schedule 12.05.2020
comment
Ya, itu mungkin masalah karena aplikasi saya tidak aktif. Tapi itu tidak berhasil, saya mendapatkan kesalahan yang sama. Aplikasi saya sudah aktif, dan saya menambahkan anotasi @Mock --tidak berfungsi. Aplikasi saya tidak aktif+menambahkan @Mock anotasi--tidak berfungsi. - person Arpan Banerjee; 12.05.2020
comment
Apakah Anda masih mendapatkan 500? - person Anurag Srivastava; 12.05.2020
comment
Jika ya, maka itu harus berasal dari kelas PropertyService tempat Anda memiliki Lingkungan Autowired. Jadi, Anda juga harus mengejek kelas Lingkungan. Namun dalam skenario nyata ini adalah semacam pengujian integrasi, bukan pengujian unit karena di sini Anda mengakses ketiga lapisan yaitu lapisan pengontrol, layanan, dan persistensi. - person Anurag Srivastava; 12.05.2020
comment
@Mock private PropertyService propertyService; @Mock private Environment env; Masih tidak berhasil. :( - person Arpan Banerjee; 12.05.2020
comment
jika saya menggunakan @SpringBootTest di atas kelas pengujian saya maka kesalahan yang sama juga, PropertyService adalah null. Tolong bantu saya. Cobalah untuk membuat ulang masalah di lokal Anda jika Anda punya waktu luang. - person Arpan Banerjee; 12.05.2020
comment
Bisakah Anda membagikan kode atau repo Anda, sehingga saya dapat memverifikasi masalahnya di lokal saya - person Anurag Srivastava; 13.05.2020
comment
tentu, ini kode sumbernya-- [github.com/Arpan619Banerjee/SpringBoot_rest_api ] - person Arpan Banerjee; 13.05.2020
comment
Maaf Arpan, saya tidak dapat menyelesaikan kode sepenuhnya karena jadwal sibuk dan memerlukan sedikit pengaturan DB yang tidak saya miliki di lokal saya sesuai kebutuhan proyek Anda .... tapi pasti saya akan mengaturnya segera Sementara itu, bisakah Anda memberi tahu saya apakah Anda melakukan pengujian integrasi atau pengujian unit? dan bisakah Anda memberikan log kesalahan Anda setelah mengejek PropertyService - person Anurag Srivastava; 14.05.2020
comment
Tidak apa-apa. Kesalahan yang saya dapatkan setelah mengejek telah disebutkan di komentar jawaban lain. - person Arpan Banerjee; 14.05.2020
comment
Arpan Saya telah memperbarui solusinya, silakan lakukan itu. - person Anurag Srivastava; 16.05.2020
comment
Terima kasih! Solusi pembaruan bekerja dengan sangat baik!. Namun masih ada satu keraguan-- Saya masih tidak dapat mengakses layanan prop di kelas pengujian saya, solusi Anda juga melakukan hardcode pada nilai authKey . Saya mencoba mendapatkannya dari PropertyService tetapi mendapat kesalahan--- Saya dapat hidup dengan melakukan hardcoding di kelas pengujian, jadi ini bukan penting, jika Anda mau dan memiliki waktu luang, Anda dapat menyelidiki masalah ini .... - person Arpan Banerjee; 16.05.2020
comment
` ModelAndView: Lihat nama = null Lihat = null Model = null FlashMap: Atribut = null MockHttpServletResponse: Status = 500 Pesan kesalahan = null Header = [Jenis Konten:teks/polos;charset=UTF-8, Panjang Konten:34] Tipe konten = text/plain;charset=UTF-8 Isi = Gagal menambahkan pelanggan karena null URL yang Diteruskan = null URL yang Dialihkan = null Cookies = []`. - person Arpan Banerjee; 16.05.2020
comment
Dan ada satu kesalahan lagi. Ini masalah besar-- kasus pengujian saya lolos meskipun saya memberikan salah authId . Silakan coba di daerah Anda dan beri tahu saya jika Anda memiliki perilaku yang sama. - person Arpan Banerjee; 16.05.2020

Dan ada satu kesalahan lagi. Ini masalah besar-- kasus pengujian saya lolos meskipun saya memberikan authId yang salah. Silakan coba di daerah Anda dan beri tahu saya jika Anda memiliki perilaku yang sama.

Tentu saja pengujian Anda akan lulus karena kode Anda hanya memeriksa kondisi dan tidak mencegah kode dieksekusi. Silakan lihat kode Anda di bawah ini:

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);

    }

Di sini dalam kondisi if Anda hanya mengeksekusi blok kode dan kemudian diinstruksikan untuk mengeksekusi blok kode yang berada di luar kondisi if.

Jadi dalam kondisi if ia tidak melakukan apa-apa. Jadi, Anda harus meningkatkan kode Anda sesuai perilaku yang diharapkan.

Jika Anda ingin mencegah eksekusi kode Anda, silakan lihat kode di bawah ini

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";
            return 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();
        e.printStackTrace();
        finalMessage = new ResponseEntity<>(message, HttpStatus.INTERNAL_SERVER_ERROR);
    }

Di sini saya telah mengatur pernyataan return dalam kondisi If.

Tetapi jika Anda ingin gagal dalam uji kasus saat ini saat Anda membandingkan pesan, silakan lihat kode di bawah ini:

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);
        }else {
            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();
        e.printStackTrace();
        finalMessage = new ResponseEntity<>(message, HttpStatus.INTERNAL_SERVER_ERROR);
    }

Di sini Anda hanya perlu mengatur blok kode yang berada di luar kondisi if di bawah bagian else.

person Anurag Srivastava    schedule 16.05.2020
comment
Ya, itu adalah kesalahan konyol di pihak saya, saya lupa pernyataan return, tapi sekarang, sudah kembali ke poin 0. Sekarang setelah menambahkan pernyataan return setelah if-check (kode contoh If you would like to prevent your code execution then please refer the code below Anda). Kelas pengujian selalu mengembalikan status 401 uauthorized. Setelah debugging saya perhatikan bahwa athKey di HomeController adalah null--seperti sebelumnya. Sudahkah Anda mencobanya di lokal Anda? Menantikan balasan Anda! - person Arpan Banerjee; 16.05.2020
comment
Hai...Apakah Anda berkesempatan mencobanya? - person Arpan Banerjee; 19.05.2020

Coba tiru PropertyService dengan @MockBean atau @Mock.

Saya perhatikan Anda kehilangan @WebMvcTest(Controller.class) di atas definisi kelas yang Anda perlukan untuk pengujian unit Pengontrol Mvc. Penjelasan

Jika @MockBean tidak berhasil.

Mencoba:

Dengan menggunakan Mockito.when(), Anda cukup mengembalikan hasil yang diinginkan/diharapkan dan kapan metode yang diinginkan dipanggil.

Gunakan Mockito.verify() untuk memastikan keinginan kapan dieksekusi.

when(propertyService.getKeytoAddCustomer()).thenReturn("Desired String");

when(customerService.addCustomer(customerObject)).thenReturn("Desired result");

//DO mvc.perform(...);

verify(propertyService).getKeytoAddCustomer();

verify(customerService).addCustomer(customerObject());

Masalah Kedua

Masalah dengan file properti yang saya asumsikan adalah karena Anda menggunakan spring.profile.active=dev tetapi file properti test/resources adalah application.properties bukan application-dev.properties meskipun itu adalah satu-satunya file properti di test/resources. Ganti nama file yang sama persis di kedua folder sumber daya dan lihat apa yang terjadi.

person Tony    schedule 12.05.2020
comment
Solusi masalah 2 tidak berhasil, nilainya masih di-hardcode, tetapi setelah menambahkan @WebMvcTest(HomeController.class) saya mendapatkan kesalahan ini---Description: Field propertyService in com.spring.liquibase.demo.controller.HomeController required a bean of type 'com.spring.liquibase.demo.utility.PropertyService' that could not be found. The injection point has the following annotations: - @org.springframework.beans.factory.annotation.Autowired(required=true) Action: Consider defining a bean of type 'com.spring.liquibase.demo.utility.PropertyService' in your configuration. - person Arpan Banerjee; 12.05.2020
comment
jika saya menggunakan @SpringBootTest di atas kelas pengujian saya maka kesalahan yang sama juga terjadi, PropertyService adalah nol. - person Arpan Banerjee; 12.05.2020
comment
Jangan gunakan @SpringBootTest. Gunakan @RunWith(SpringRunner.class) sebagai gantinya. Apakah Anda mendefinisikan @MockBean PropertyService propertyService; seperti itu? - person Tony; 12.05.2020
comment
Saya menggunakan jUnit5 jadi @RunWith diganti dengan @ExtendWith(SpringExtension.class) saya menggunakan ini - person Arpan Banerjee; 12.05.2020