portaldacalheta.pt
  • หลัก
  • ไลฟ์สไตล์
  • บุคลากรและทีมงานของผลิตภัณฑ์
  • ชีวิตนักออกแบบ
  • อื่น ๆ
ส่วนหลัง

สร้างด้วยความมั่นใจ: คำแนะนำสำหรับการทดสอบ JUnit



ด้วยความก้าวหน้าของเทคโนโลยีและอุตสาหกรรมที่เปลี่ยนจากแบบจำลอง Waterfall เป็น Agile และตอนนี้ไปสู่ ​​DevOps การเปลี่ยนแปลงและการปรับปรุงในแอปพลิเคชันจะถูกนำไปใช้กับการผลิตในนาทีที่เกิดขึ้น เมื่อโค้ดถูกนำไปใช้งานจริงอย่างรวดเร็วเราจึงต้องมั่นใจว่าการเปลี่ยนแปลงของเราได้ผลและไม่ทำลายฟังก์ชันการทำงานที่มีมาก่อน

เพื่อสร้างความมั่นใจนี้เราต้องมี กรอบ สำหรับการทดสอบการถดถอยอัตโนมัติ สำหรับการทดสอบการถดถอยมีการทดสอบมากมายที่ควรดำเนินการจากมุมมองระดับ API แต่ในที่นี้เราจะกล่าวถึงการทดสอบหลัก 2 ประเภทดังนี้



  • การทดสอบหน่วย โดยที่การทดสอบใด ๆ จะครอบคลุมหน่วยที่เล็กที่สุดของโปรแกรม (ฟังก์ชันหรือขั้นตอน) อาจใช้หรือไม่ใช้พารามิเตอร์อินพุตบางค่าและอาจส่งคืนค่าบางค่าหรือไม่ก็ได้
  • การทดสอบการผสานรวม ซึ่งแต่ละหน่วยจะได้รับการทดสอบร่วมกันเพื่อตรวจสอบว่าหน่วยทั้งหมดโต้ตอบกันตามที่คาดไว้หรือไม่

มีกรอบมากมายสำหรับทุกภาษาการเขียนโปรแกรม เราจะเน้นไปที่การเขียนหน่วยและการทดสอบการรวมสำหรับเว็บแอปที่เขียน Java กรอบฤดูใบไม้ผลิ



แผนภูมิเปรียบเทียบซอฟต์แวร์การจัดการโครงการ

โดยส่วนใหญ่เราจะเขียนวิธีการในชั้นเรียนและสิ่งเหล่านี้จะโต้ตอบกับเมธอดของคลาสอื่น ๆ ในโลกปัจจุบันโดยเฉพาะอย่างยิ่งใน แอปพลิเคชันระดับองค์กร - ความซับซ้อนของแอปพลิเคชันคือเมธอดเดียวอาจเรียกมากกว่าหนึ่งวิธีของหลายคลาส ดังนั้นเมื่อเขียนการทดสอบหน่วยสำหรับวิธีดังกล่าวเราจำเป็นต้องมีวิธีส่งคืนข้อมูลจำลองจากการเรียกเหล่านั้น เนื่องจากจุดประสงค์ของการทดสอบหน่วยนี้คือการทดสอบเพียงวิธีเดียวไม่ใช่การเรียกทั้งหมดที่วิธีการนี้ทำขึ้น




มาเริ่มการทดสอบหน่วย Java ในฤดูใบไม้ผลิโดยใช้กรอบงาน JUnit เราจะเริ่มจากสิ่งที่คุณอาจเคยได้ยินนั่นคือการล้อเลียน

การล้อเลียนคืออะไรและจะเข้ามาในภาพเมื่อใด

สมมติว่าคุณมีคลาส CalculateArea ซึ่งมีฟังก์ชัน calculateArea(Type type, Double... args) ซึ่งคำนวณพื้นที่ของรูปร่างของประเภทที่กำหนด (วงกลมสี่เหลี่ยมจัตุรัสหรือสี่เหลี่ยมผืนผ้า)



รหัสมีลักษณะเช่นนี้ในแอปพลิเคชันปกติซึ่งไม่ใช้การฉีดขึ้นต่อกัน:

public class CalculateArea { SquareService squareService; RectangleService rectangleService; CircleService circleService; CalculateArea(SquareService squareService, RectangleService rectangeService, CircleService circleService) { this.squareService = squareService; this.rectangleService = rectangeService; this.circleService = circleService; } public Double calculateArea(Type type, Double... r ) { switch (type) { case RECTANGLE: if(r.length >=2) return rectangleService.area(r[0],r[1]); else throw new RuntimeException('Missing required params'); case SQUARE: if(r.length >=1) return squareService.area(r[0]); else throw new RuntimeException('Missing required param'); case CIRCLE: if(r.length >=1) return circleService.area(r[0]); else throw new RuntimeException('Missing required param'); default: throw new RuntimeException('Operation not supported'); } } } public class SquareService { public Double area(double r) { return r * r; } } public class RectangleService { public Double area(Double r, Double h) { return r * h; } } public class CircleService { public Double area(Double r) { return Math.PI * r * r; } } public enum Type { RECTANGLE,SQUARE,CIRCLE; }

ตอนนี้ถ้าเราต้องการทดสอบหน่วยฟังก์ชัน calculateArea() ของชั้นเรียน CalculateArea ดังนั้นแรงจูงใจของเราควรตรวจสอบว่า switch กรณีและเงื่อนไขข้อยกเว้นทำงาน เราไม่ควรทดสอบว่าบริการรูปร่างส่งคืนค่าที่ถูกต้องหรือไม่เพราะตามที่กล่าวไว้ก่อนหน้านี้แรงจูงใจของการทดสอบหน่วยฟังก์ชันคือการทดสอบตรรกะของฟังก์ชันไม่ใช่ตรรกะของการเรียกใช้ฟังก์ชัน



ดังนั้นเราจะจำลองค่าที่ส่งคืนโดยฟังก์ชันบริการแต่ละรายการ (เช่น rectangleService.area() และทดสอบฟังก์ชันการโทร (เช่น CalculateArea.calculateArea()) ตามค่าที่เยาะเย้ยเหล่านั้น

กรณีทดสอบง่ายๆสำหรับบริการสี่เหลี่ยมผืนผ้า - ทดสอบว่า calculateArea() โทรจริง rectangleService.area() ด้วยพารามิเตอร์ที่ถูกต้อง - จะมีลักษณะดังนี้:



import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; public class CalculateAreaTest { RectangleService rectangleService; SquareService squareService; CircleService circleService; CalculateArea calculateArea; @Before public void init() { rectangleService = Mockito.mock(RectangleService.class); squareService = Mockito.mock(SquareService.class); circleService = Mockito.mock(CircleService.class); calculateArea = new CalculateArea(squareService,rectangleService,circleService); } @Test public void calculateRectangleAreaTest() { Mockito.when(rectangleService.area(5.0d,4.0d)).thenReturn(20d); Double calculatedArea = this.calculateArea.calculateArea(Type.RECTANGLE, 5.0d, 4.0d); Assert.assertEquals(new Double(20d),calculatedArea); } }

สองบรรทัดหลักที่ควรทราบ ได้แก่ :

  • rectangleService = Mockito.mock(RectangleService.class); - สิ่งนี้ทำให้เกิดการเยาะเย้ยซึ่งไม่ใช่วัตถุจริง แต่เป็นการล้อเลียน
  • Mockito.when(rectangleService.area(5.0d,4.0d)).thenReturn(20d); - สิ่งนี้กล่าวว่าเมื่อถูกล้อเลียนและ rectangleService วัตถุ area เรียกวิธีการด้วยพารามิเตอร์ที่ระบุจากนั้นส่งคืน 20d

ตอนนี้จะเกิดอะไรขึ้นเมื่อโค้ดด้านบนเป็นส่วนหนึ่งของแอปพลิเคชัน Spring



import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class CalculateArea { SquareService squareService; RectangleService rectangleService; CircleService circleService; public CalculateArea(@Autowired SquareService squareService, @Autowired RectangleService rectangeService, @Autowired CircleService circleService) { this.squareService = squareService; this.rectangleService = rectangeService; this.circleService = circleService; } public Double calculateArea(Type type, Double... r ) { // (same implementation as before) } }

ที่นี่เรามีคำอธิบายประกอบสองรายการสำหรับ Spring framework ที่เป็นพื้นฐานเพื่อตรวจจับในเวลาเริ่มต้นบริบท:

  • @Component: สร้างชนิดของถั่ว CalculateArea
  • @Autowired: ค้นหาถั่ว rectangleService, squareService และ circleService แล้วฉีดเข้าไปในถั่ว calculatedArea

ในทำนองเดียวกันเราสร้างถั่วสำหรับคลาสอื่น ๆ ด้วย:



import org.springframework.stereotype.Service; @Service public class SquareService { public Double area(double r) { return r*r; } } import org.springframework.stereotype.Service; @Service public class CircleService { public Double area(Double r) { return Math.PI * r * r; } } import org.springframework.stereotype.Service; @Service public class RectangleService { public Double area(Double r, Double h) { return r*h; } }

ตอนนี้ถ้าเราเรียกใช้การทดสอบผลลัพธ์จะเหมือนกัน เราใช้การฉีดตัวสร้างที่นี่และโชคดีที่ไม่ต้องเปลี่ยนกรณีทดสอบของเรา

แต่มีอีกวิธีหนึ่งในการฉีดถั่วของรูปสี่เหลี่ยมจัตุรัสวงกลมและสี่เหลี่ยมผืนผ้า: การฉีดสนาม หากเราใช้สิ่งนั้นกรณีทดสอบของเราจะต้องมีการเปลี่ยนแปลงเล็กน้อย

เราจะไม่พูดถึงกลไกการฉีดแบบใดที่ดีกว่าเนื่องจากไม่ได้อยู่ในขอบเขตของบทความ แต่เราสามารถพูดได้ว่า: ไม่ว่าคุณจะใช้กลไกแบบใดในการฉีดถั่วก็มีวิธีเขียนการทดสอบ JUnit เสมอ

ในกรณีของการแทรกฟิลด์รหัสจะมีลักษณะดังนี้:

@Component public class CalculateArea { @Autowired SquareService squareService; @Autowired RectangleService rectangleService; @Autowired CircleService circleService; public Double calculateArea(Type type, Double... r ) { // (same implementation as before) } }

หมายเหตุ: เนื่องจากเราใช้การแทรกฟิลด์จึงไม่จำเป็นต้องมีคอนสตรัคเตอร์ที่กำหนดพารามิเตอร์ดังนั้นอ็อบเจ็กต์จึงถูกสร้างขึ้นโดยใช้ค่าเริ่มต้นและค่าจะถูกกำหนดโดยใช้กลไกการแทรกฟิลด์

รหัสสำหรับคลาสบริการของเรายังคงเหมือนเดิม แต่รหัสสำหรับคลาสทดสอบมีดังนี้:

public class CalculateAreaTest { @Mock RectangleService rectangleService; @Mock SquareService squareService; @Mock CircleService circleService; @InjectMocks CalculateArea calculateArea; @Before public void init() { MockitoAnnotations.initMocks(this); } @Test public void calculateRectangleAreaTest() { Mockito.when(rectangleService.area(5.0d,4.0d)).thenReturn(20d); Double calculatedArea = this.calculateArea.calculateArea(Type.RECTANGLE, 5.0d, 4.0d); Assert.assertEquals(new Double(20d),calculatedArea); } }

มีบางสิ่งที่แตกต่างกันที่นี่: ไม่ใช่พื้นฐาน แต่เป็นวิธีที่เราบรรลุเป้าหมาย

ประการแรกวิธีที่เราล้อเลียนวัตถุของเรา: เราใช้ @Mock คำอธิบายประกอบพร้อมด้วย initMocks() เพื่อสร้างล้อเลียน ประการที่สองเราฉีด mocks ลงในวัตถุจริงโดยใช้ @InjectMocks พร้อมด้วย initMocks().

นี่เป็นเพียงการลดจำนวนบรรทัดของโค้ด

นักวิ่งทดสอบคืออะไรและมีนักวิ่งประเภทใดบ้าง?

ในตัวอย่างข้างต้นนักวิ่งขั้นพื้นฐานที่ใช้ในการทดสอบทั้งหมดคือ BlockJUnit4ClassRunner ซึ่งตรวจจับคำอธิบายประกอบทั้งหมดและเรียกใช้การทดสอบทั้งหมดตามนั้น

หากเราต้องการฟังก์ชันเพิ่มเติมเราอาจเขียนนักวิ่งที่กำหนดเอง ตัวอย่างเช่นในคลาสทดสอบข้างต้นหากเราต้องการข้ามบรรทัด MockitoAnnotations.initMocks(this); จากนั้นเราสามารถใช้นักวิ่งอื่นที่สร้างขึ้นจาก BlockJUnit4ClassRunner เช่น MockitoJUnitRunner.

การใช้ MockitoJUnitRunner เราไม่จำเป็นต้องเริ่มต้นล้อเลียนและฉีดมันด้วยซ้ำ ซึ่งจะทำได้โดย MockitoJUnitRunner เพียงแค่อ่านคำอธิบายประกอบ

(นอกจากนี้ยังมี SpringJUnit4ClassRunner ซึ่งเริ่มต้น ApplicationContext ที่จำเป็นสำหรับการทดสอบการรวม Spring เช่นเดียวกับ ApplicationContext ที่สร้างขึ้นเมื่อแอปพลิเคชัน Spring เริ่มต้นซึ่งเราจะกล่าวถึงในภายหลัง)

การล้อเลียนบางส่วน

เมื่อเราต้องการให้ออบเจ็กต์ในคลาสทดสอบล้อเลียนเมธอดบางอย่าง แต่ยังเรียกเมธอดจริงบางอย่างเราก็จำเป็นต้องมีการเยาะเย้ยบางส่วน สิ่งนี้ทำได้โดย @Spy ใน JUnit

ไม่เหมือนกับการใช้ @Mock ร่วมกับ @Spy วัตถุจริงจะถูกสร้างขึ้น แต่วิธีการของวัตถุนั้นสามารถล้อเลียนหรือเรียกได้ว่าเป็นอะไรก็ได้ที่เราต้องการ

ตัวอย่างเช่นถ้า area วิธีการในคลาส RectangleService เรียกวิธีพิเศษ log() และเราต้องการพิมพ์บันทึกนั้นจริงๆจากนั้นรหัสจะเปลี่ยนเป็นดังนี้:

@Service public class RectangleService { public Double area(Double r, Double h) { log(); return r*h; } public void log() { System.out.println('skip this'); } }

ถ้าเราเปลี่ยน @Mock คำอธิบายประกอบของ rectangleService เป็น @Spy และทำการเปลี่ยนแปลงโค้ดบางอย่างตามที่แสดงด้านล่างจากนั้นในผลลัพธ์เราจะเห็นการพิมพ์บันทึก แต่วิธีการ area() จะถูกล้อเลียน นั่นคือฟังก์ชันดั้งเดิมถูกเรียกใช้เพื่อผลข้างเคียงเท่านั้น ค่าที่ส่งคืนจะถูกแทนที่ด้วยค่าที่ถูกเยาะเย้ย

@RunWith(MockitoJUnitRunner.class) public class CalculateAreaTest { @Spy RectangleService rectangleService; @Mock SquareService squareService; @Mock CircleService circleService; @InjectMocks CalculateArea calculateArea; @Test public void calculateRectangleAreaTest() { Mockito.doCallRealMethod().when(rectangleService).log(); Mockito.when(rectangleService.area(5.0d,4.0d)).thenReturn(20d); Double calculatedArea = this.calculateArea.calculateArea(Type.RECTANGLE, 5.0d, 4.0d); Assert.assertEquals(new Double(20d),calculatedArea); } }

เราจะไปเกี่ยวกับการทดสอบ Controller หรือ RequestHandler?

จากสิ่งที่เราเรียนรู้ข้างต้นรหัสทดสอบของคอนโทรลเลอร์สำหรับตัวอย่างของเราจะเป็นดังนี้:

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class AreaController { @Autowired CalculateArea calculateArea; @RequestMapping(value = 'api/area', method = RequestMethod.GET) @ResponseBody public ResponseEntity calculateArea( @RequestParam('type') String type, @RequestParam('param1') String param1, @RequestParam(value = 'param2', required = false) String param2 ) { try { Double area = calculateArea.calculateArea( Type.valueOf(type), Double.parseDouble(param1), Double.parseDouble(param2) ); return new ResponseEntity(area, HttpStatus.OK); } catch (Exception e) { return new ResponseEntity(e.getCause(), HttpStatus.INTERNAL_SERVER_ERROR); } } } import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @RunWith(MockitoJUnitRunner.class) public class AreaControllerTest { @Mock CalculateArea calculateArea; @InjectMocks AreaController areaController; @Test public void calculateAreaTest() { Mockito .when(calculateArea.calculateArea(Type.RECTANGLE,5.0d, 4.0d)) .thenReturn(20d); ResponseEntity responseEntity = areaController.calculateArea('RECTANGLE', '5', '4'); Assert.assertEquals(HttpStatus.OK,responseEntity.getStatusCode()); Assert.assertEquals(20d,responseEntity.getBody()); } }

เมื่อดูรหัสทดสอบคอนโทรลเลอร์ด้านบนก็ใช้งานได้ดี แต่มีปัญหาพื้นฐานอย่างหนึ่ง: ทดสอบเฉพาะการเรียกใช้เมธอดเท่านั้นไม่ใช่การเรียก API จริง กรณีทดสอบทั้งหมดที่พารามิเตอร์ API และสถานะของการเรียก API จำเป็นต้องทดสอบสำหรับอินพุตที่แตกต่างกันหายไป

รหัสนี้ดีกว่า:

import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup; @RunWith(SpringJUnit4ClassRunner.class) public class AreaControllerTest { @Mock CalculateArea calculateArea; @InjectMocks AreaController areaController; MockMvc mockMvc; @Before public void init() { mockMvc = standaloneSetup(areaController).build(); } @Test public void calculateAreaTest() throws Exception { Mockito .when(calculateArea.calculateArea(Type.RECTANGLE,5.0d, 4.0d)) .thenReturn(20d); mockMvc.perform( MockMvcRequestBuilders.get('/api/area?type=RECTANGLE¶m1=5¶m2=4') ) .andExpect(status().isOk()) .andExpect(content().string('20.0')); } }

ที่นี่เราสามารถดูวิธี MockMvc รับหน้าที่เรียก API จริง นอกจากนี้ยังมีผู้จับคู่พิเศษเช่น status() และ content() ซึ่งทำให้ง่ายต่อการตรวจสอบเนื้อหา

การทดสอบการรวม Java โดยใช้ JUnit และ Mocks

ตอนนี้เรารู้แล้วว่าแต่ละหน่วยของโค้ดทำงานได้แล้วตรวจสอบให้แน่ใจว่าพวกเขาโต้ตอบกันตามที่เราคาดหวัง

ขั้นแรกเราต้องสร้างอินสแตนซ์ของถั่วทั้งหมดซึ่งเป็นสิ่งเดียวกับที่เกิดขึ้นในช่วงเวลาของการเริ่มต้นบริบท Spring ระหว่างการเริ่มต้นแอปพลิเคชัน

สำหรับสิ่งนี้เรากำหนดถั่วทั้งหมดในชั้นเรียนสมมติว่า TestConfig.java:

import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class TestConfig { @Bean public AreaController areaController() { return new AreaController(); } @Bean public CalculateArea calculateArea() { return new CalculateArea(); } @Bean public RectangleService rectangleService() { return new RectangleService(); } @Bean public SquareService squareService() { return new SquareService(); } @Bean public CircleService circleService() { return new CircleService(); } }

ตอนนี้เรามาดูกันว่าเราใช้คลาสนี้อย่างไรและเขียนแบบทดสอบบูรณาการ:

import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = {TestConfig.class}) public class AreaControllerIntegrationTest { @Autowired AreaController areaController; MockMvc mockMvc; @Before public void init() { mockMvc = standaloneSetup(areaController).build(); } @Test public void calculateAreaTest() throws Exception { mockMvc.perform( MockMvcRequestBuilders.get('/api/area?type=RECTANGLE¶m1=5¶m2=4') ) .andExpect(status().isOk()) .andExpect(content().string('20.0')); } }

มีการเปลี่ยนแปลงบางอย่างที่นี่:

  • @ContextConfiguration(classes = {TestConfig.class}) - สิ่งนี้จะบอกกรณีทดสอบที่มีคำจำกัดความของ bean ทั้งหมดอยู่
  • ตอนนี้แทนที่จะเป็น @InjectMocks เราใช้:
@Autowired AreaController areaController;

อย่างอื่นยังคงเหมือนเดิม หากเราดีบักการทดสอบเราจะเห็นว่าโค้ดทำงานจนถึงบรรทัดสุดท้ายของ area() วิธีการใน RectangleService ที่ไหน return r*h คำนวณ กล่าวอีกนัยหนึ่งตรรกะทางธุรกิจที่แท้จริงทำงาน

นี่ไม่ได้หมายความว่าไม่มีการเยาะเย้ยการเรียกเมธอดหรือการเรียกฐานข้อมูลที่มีอยู่ในการทดสอบการรวม ในตัวอย่างข้างต้นไม่มีการใช้บริการหรือฐานข้อมูลของบุคคลที่สามดังนั้นเราจึงไม่จำเป็นต้องใช้ล้อเลียน ในชีวิตจริงแอปพลิเคชันดังกล่าวหายากและเรามักจะโดนฐานข้อมูลหรือ API ของบุคคลที่สามหรือทั้งสองอย่าง ในกรณีนี้เมื่อเราสร้าง bean ใน TestConfig คลาสเราไม่ได้สร้างออบเจ็กต์จริง แต่เป็นวัตถุจำลองและใช้มันทุกที่ที่ต้องการ

โบนัส: วิธีสร้างข้อมูลการทดสอบวัตถุขนาดใหญ่

บ่อยครั้งสิ่งที่หยุดยั้งนักพัฒนาส่วนหลังในการเขียนหน่วยหรือการทดสอบการรวมก็คือข้อมูลการทดสอบที่เราต้องเตรียมสำหรับการทดสอบทุกครั้ง

โดยปกติหากข้อมูลมีขนาดเล็กพอโดยมีตัวแปรหนึ่งหรือสองตัวก็ทำได้ง่ายเพียงแค่สร้างออบเจ็กต์ของคลาสข้อมูลทดสอบและกำหนดค่าบางอย่าง

ตัวอย่างเช่นหากเราคาดหวังว่าวัตถุจำลองจะส่งคืนวัตถุอื่นเมื่อมีการเรียกใช้ฟังก์ชันบนวัตถุจำลองเราจะทำสิ่งนี้:

Class1 object = new Class1(); object.setVariable1(1); object.setVariable2(2);

จากนั้นในการใช้วัตถุนี้เราจะทำสิ่งนี้:

Mockito.when(service.method(arguments...)).thenReturn(object);

นี่ใช้ได้ดีในตัวอย่าง JUnit ด้านบน แต่เมื่อตัวแปรสมาชิกในข้างต้น Class1 ชั้นเรียนเพิ่มขึ้นเรื่อย ๆ จากนั้นการตั้งค่าแต่ละฟิลด์จะกลายเป็นความเจ็บปวด บางครั้งมันอาจเกิดขึ้นที่คลาสมีสมาชิกคลาสอื่นที่ไม่ใช่คลาสดั้งเดิมกำหนดไว้ จากนั้นการสร้างออบเจ็กต์ของคลาสนั้นและการตั้งค่าฟิลด์ที่จำเป็นแต่ละฟิลด์จะช่วยเพิ่มความพยายามในการพัฒนาเพื่อให้บรรลุผลสำเร็จบางอย่าง

วิธีแก้ปัญหาคือสร้างสคีมา JSON ของคลาสด้านบนและเพิ่มข้อมูลที่เกี่ยวข้องในไฟล์ JSON หนึ่งครั้ง ตอนนี้อยู่ในชั้นทดสอบที่เราสร้าง Class1 วัตถุเราไม่จำเป็นต้องสร้างวัตถุด้วยตนเอง เราอ่านไฟล์ JSON แทนและโดยใช้ ObjectMapper แมปลงในไฟล์ที่จำเป็น Class1 ชั้น:

ObjectMapper objectMapper = new ObjectMapper(); Class1 object = objectMapper.readValue( new String(Files.readAllBytes( Paths.get('src/test/resources/'+fileName)) ), Class1.class );

นี่เป็นความพยายามเพียงครั้งเดียวในการสร้างไฟล์ JSON และเพิ่มค่าให้กับไฟล์ การทดสอบใหม่ใด ๆ หลังจากนั้นสามารถใช้สำเนาของไฟล์ JSON ที่มีการเปลี่ยนแปลงฟิลด์ตามความต้องการของการทดสอบใหม่

พื้นฐานของ JUnit: แนวทางที่หลากหลายและทักษะที่โอนย้ายได้

เป็นที่ชัดเจนว่ามีหลายวิธีในการเขียนการทดสอบหน่วย Java ขึ้นอยู่กับวิธีที่เราเลือกฉีดถั่ว น่าเสียดายที่บทความส่วนใหญ่ในหัวข้อนี้มักจะคิดว่ามีเพียงวิธีเดียวดังนั้นจึงสับสนได้ง่ายโดยเฉพาะอย่างยิ่งเมื่อทำงานกับโค้ดที่เขียนขึ้นภายใต้สมมติฐานอื่น หวังว่าแนวทางของเราจะช่วยให้นักพัฒนาซอฟต์แวร์ประหยัดเวลาในการหาวิธีล้อเลียนที่ถูกต้องและควรใช้นักวิ่งทดสอบตัวใด

โดยไม่คำนึงถึงภาษาหรือเฟรมเวิร์กที่เราใช้ - อาจเป็นเวอร์ชันใหม่ของ Spring หรือ JUnit ก็ตาม - ฐานแนวคิดยังคงเหมือนเดิมตามที่อธิบายไว้ในบทแนะนำ JUnit ข้างต้น ขอให้สนุกกับการทดสอบ!

ทำความเข้าใจพื้นฐาน

คุณเขียน Unit Test ใน Java ได้อย่างไร?

JUnit เป็นเฟรมเวิร์กที่มีชื่อเสียงที่สุดสำหรับการเขียนการทดสอบหน่วยใน Java คุณเขียนวิธีการทดสอบที่เรียกใช้วิธีการจริงที่จะทดสอบ กรณีทดสอบจะตรวจสอบลักษณะการทำงานของโค้ดโดยยืนยันค่าที่ส่งคืนกับค่าที่คาดไว้โดยกำหนดพารามิเตอร์ที่ส่งผ่าน

กรอบการทดสอบหน่วยที่ดีที่สุดสำหรับ Java คืออะไร?

นักพัฒนา Java ส่วนใหญ่ยอมรับว่า JUnit เป็นกรอบการทดสอบหน่วยที่ดีที่สุด เป็นมาตรฐานโดยพฤตินัยตั้งแต่ปี 1997 และแน่นอนว่าได้รับการสนับสนุนจำนวนมากที่สุดเมื่อเทียบกับเฟรมเวิร์กการทดสอบหน่วย Java อื่น ๆ

การทดสอบหน่วยในการเขียนโปรแกรมคืออะไร?

ในการทดสอบหน่วยแต่ละหน่วย (โดยปกติวิธีการของวัตถุถือเป็น 'หน่วย') จะถูกทดสอบในรูปแบบอัตโนมัติ

ทำไมเราถึงใช้การทดสอบ JUnit

การทดสอบ JUnit ใช้เพื่อทดสอบพฤติกรรมของเมธอดในคลาสที่เราเขียน เราทดสอบวิธีการเพื่อให้ได้ผลลัพธ์ที่คาดหวังและในบางครั้งกรณีที่มีข้อยกเว้น - ว่าวิธีนี้สามารถจัดการกับข้อยกเว้นในแบบที่เราต้องการได้หรือไม่

การใช้งาน JUnit คืออะไร?

JUnit เป็นเฟรมเวิร์กที่มีคลาสและวิธีการต่างๆมากมายในการเขียนแบบทดสอบหน่วยอย่างง่ายดาย

การปรับประสิทธิภาพของฐานข้อมูลคืออะไร

JUnit เป็นโอเพ่นซอร์สหรือไม่

ใช่ JUnit เป็นโครงการโอเพ่นซอร์สซึ่งดูแลโดยนักพัฒนาที่ใช้งานอยู่หลายคน

JUnit สำคัญไฉน?

JUnit ลดมาตรฐานสำเร็จรูปที่นักพัฒนาต้องใช้เมื่อเขียนการทดสอบหน่วย

ใครเป็นผู้คิดค้น JUnit?

Kent Beck และ Erich Gamma เริ่มสร้าง JUnit ปัจจุบันโครงการโอเพนซอร์สมีผู้ร่วมให้ข้อมูลมากกว่าร้อยคน

บทช่วยสอนสำหรับวิศวกรรมย้อนกลับ API ส่วนตัวของซอฟต์แวร์ของคุณ: การแฮ็กที่นอนของคุณ

เทคโนโลยี

บทช่วยสอนสำหรับวิศวกรรมย้อนกลับ API ส่วนตัวของซอฟต์แวร์ของคุณ: การแฮ็กที่นอนของคุณ
Visual Programming with Node-Red: การเชื่อมต่ออินเทอร์เน็ตในทุกสิ่งอย่างง่ายดาย

Visual Programming with Node-Red: การเชื่อมต่ออินเทอร์เน็ตในทุกสิ่งอย่างง่ายดาย

ส่วนหลัง

โพสต์ยอดนิยม
การบันทึกผลิตภัณฑ์ X - กรณีศึกษาการคิดเชิงออกแบบ
การบันทึกผลิตภัณฑ์ X - กรณีศึกษาการคิดเชิงออกแบบ
ผู้แทนฝ่ายพัฒนาการขาย SMB
ผู้แทนฝ่ายพัฒนาการขาย SMB
Python Logging: บทช่วยสอนเชิงลึก
Python Logging: บทช่วยสอนเชิงลึก
การขุดข้อมูลสำหรับการวิเคราะห์เครือข่ายสังคมออนไลน์แบบคาดเดา
การขุดข้อมูลสำหรับการวิเคราะห์เครือข่ายสังคมออนไลน์แบบคาดเดา
ผู้อำนวยการฝ่ายบริการลูกค้าองค์กรผลิตภัณฑ์และบริการอุตสาหกรรม
ผู้อำนวยการฝ่ายบริการลูกค้าองค์กรผลิตภัณฑ์และบริการอุตสาหกรรม
 
การคาดการณ์การลงทุนในปี 2560: สัญญาณของความเหนื่อยล้า
การคาดการณ์การลงทุนในปี 2560: สัญญาณของความเหนื่อยล้า
เกิดอะไรขึ้นกับ BlackBerry: Zombie Stock หรือ Comeback King?
เกิดอะไรขึ้นกับ BlackBerry: Zombie Stock หรือ Comeback King?
Erik Stettler เข้าร่วม ApeeScape ในตำแหน่งหัวหน้านักเศรษฐศาสตร์
Erik Stettler เข้าร่วม ApeeScape ในตำแหน่งหัวหน้านักเศรษฐศาสตร์
คู่มือพื้นฐานสำหรับการใช้งานมือถือ
คู่มือพื้นฐานสำหรับการใช้งานมือถือ
สร้างส่วนประกอบทางรถไฟที่เพรียวบางด้วยวัตถุทับทิมเก่า ๆ
สร้างส่วนประกอบทางรถไฟที่เพรียวบางด้วยวัตถุทับทิมเก่า ๆ
โพสต์ยอดนิยม
  • console.error(`เป็นข้อผิดพลาดที่ทราบว่าสามารถทำลาย npm โปรดอัปเดตเป็นอย่างน้อย ${r
  • วิธีใช้ twitter api python
  • วิธีใช้ไฟล์ส่วนหัวใน c++
  • วิธีเขียนรหัสซอฟต์แวร์
  • เว็บไซต์หาคู่ที่ประสบความสำเร็จสูงสุด 2016
  • อัตรารายชั่วโมงของสัญญาเทียบกับเครื่องคำนวณเงินเดือน
  • ใช้ github เพื่อโฮสต์เว็บไซต์
หมวดหมู่
  • ไลฟ์สไตล์
  • บุคลากรและทีมงานของผลิตภัณฑ์
  • ชีวิตนักออกแบบ
  • อื่น ๆ
  • © 2022 | สงวนลิขสิทธิ์

    portaldacalheta.pt