อย่าใช้ช่องทางส่วนตัวในทางที่ผิดโดยได้รับ / สะท้อน
การใช้การไตร่ตรองอย่างที่ทำในหลายคำตอบที่นี่เป็นสิ่งที่เราสามารถหลีกเลี่ยงได้
มันนำค่าเล็กน้อยมาที่นี่ในขณะที่นำเสนอข้อบกพร่องหลายประการ:
- เราตรวจพบปัญหาการสะท้อนที่รันไทม์เท่านั้น (เช่น: ฟิลด์ที่ไม่มีอยู่อีกต่อไป)
- เราต้องการ encapsulation แต่ไม่ใช่คลาสทึบแสงที่ซ่อนการพึ่งพาที่ควรมองเห็นและทำให้คลาสทึบแสงมากขึ้นและทดสอบน้อยลง
- มันส่งเสริมการออกแบบที่ไม่ดี
@Value String field
วันนี้คุณประกาศ พรุ่งนี้คุณสามารถประกาศ5
หรือ10
ของพวกเขาในชั้นเรียนนั้นและคุณอาจไม่รู้ตัวเลยว่าคุณลดการออกแบบชั้นเรียนลง ด้วยวิธีการที่ชัดเจนยิ่งขึ้นในการตั้งค่าเขตข้อมูลเหล่านี้ (เช่นตัวสร้าง) คุณจะคิดสองครั้งก่อนที่จะเพิ่มเขตข้อมูลเหล่านี้ทั้งหมดและคุณอาจจะแค็ปซูลเขตข้อมูลเหล่านั้นลงในคลาสและการใช้งาน@ConfigurationProperties
อื่น
ทำให้ชั้นเรียนของคุณสามารถทดสอบได้ทั้งแบบรวมและรวมเข้าด้วยกัน
เพื่อให้สามารถเขียนทั้งการทดสอบหน่วยธรรมดา (ที่ไม่มีคอนเทนเนอร์สปริงที่รันอยู่) และการทดสอบการรวมสำหรับคลาสคอมโพเนนต์ Spring ของคุณคุณต้องทำให้คลาสนี้ใช้งานได้ทั้งแบบมีหรือไม่มีสปริง
การเรียกใช้คอนเทนเนอร์ในการทดสอบหน่วยเมื่อไม่ต้องการนั้นเป็นวิธีปฏิบัติที่ไม่ดีที่ทำให้การสร้างในท้องถิ่นช้าลง: คุณไม่ต้องการสิ่งนั้น
ฉันเพิ่มคำตอบนี้เพราะไม่มีคำตอบที่นี่ดูเหมือนจะแสดงความแตกต่างนี้และดังนั้นพวกเขาจึงใช้ภาชนะที่ทำงานอย่างเป็นระบบ
ดังนั้นฉันคิดว่าคุณควรย้ายคุณสมบัตินี้ถูกกำหนดเป็นภายในของคลาส:
@Component
public class Foo{
@Value("${property.value}") private String property;
//...
}
เป็นพารามิเตอร์ตัวสร้างที่จะถูกฉีดโดย Spring:
@Component
public class Foo{
private String property;
public Foo(@Value("${property.value}") String property){
this.property = property;
}
//...
}
ตัวอย่างการทดสอบหน่วย
คุณสามารถสร้างอินสแตนซ์Foo
โดยไม่มีสปริงและฉีดค่าใด ๆproperty
ขอบคุณผู้สร้าง:
public class FooTest{
Foo foo = new Foo("dummyValue");
@Test
public void doThat(){
...
}
}
ตัวอย่างการทดสอบการรวม
คุณสามารถฉีดคุณสมบัติในบริบทด้วย Spring Boot ด้วยวิธีง่ายๆนี้ด้วยproperties
คุณสมบัติของ@SpringBootTest
:
@SpringBootTest(properties="property.value=dummyValue")
public class FooTest{
@Autowired
Foo foo;
@Test
public void doThat(){
...
}
}
คุณสามารถใช้เป็นทางเลือก @TestPropertySource
แต่เพิ่มหมายเหตุประกอบเพิ่มเติม:
@SpringBootTest
@TestPropertySource("property.value=dummyValue")
public class FooTest{ ...}
สำหรับ Spring (ที่ไม่มี Spring Boot) มันควรจะซับซ้อนกว่านี้เล็กน้อย แต่เนื่องจากฉันไม่ได้ใช้ Spring โดยไม่ต้อง Spring Boot มานานฉันไม่ชอบพูดสิ่งที่โง่
ตามหมายเหตุด้านข้าง: หากคุณมีหลาย@Value
ฟิลด์ที่จะตั้งค่าการแยกออกเป็นคลาสที่มีคำอธิบายประกอบ@ConfigurationProperties
นั้นมีความเกี่ยวข้องมากกว่าเพราะเราไม่ต้องการตัวสร้างที่มีอาร์กิวเมนต์มากเกินไป