กรอบที่ดีที่สุดสำหรับการสร้างวัตถุจำลองใน Java คืออะไร ทำไม? ข้อดีและข้อเสียของแต่ละเฟรมเวิร์กคืออะไร
กรอบที่ดีที่สุดสำหรับการสร้างวัตถุจำลองใน Java คืออะไร ทำไม? ข้อดีและข้อเสียของแต่ละเฟรมเวิร์กคืออะไร
คำตอบ:
ผมเคยมีความสำเร็จที่ดีโดยใช้Mockito
เมื่อฉันลองเรียนรู้เกี่ยวกับ JMock และ EasyMock ฉันพบว่าช่วงการเรียนรู้นั้นค่อนข้างชัน (แม้ว่าอาจเป็นเพียงฉัน)
ฉันชอบ Mockito เพราะไวยากรณ์ที่เรียบง่ายและสะอาดซึ่งฉันสามารถเข้าใจได้อย่างรวดเร็ว ไวยากรณ์น้อยที่สุดได้รับการออกแบบมาเพื่อรองรับกรณีทั่วไปได้เป็นอย่างดีแม้ว่าบางครั้งฉันต้องทำสิ่งที่ซับซ้อนกว่านี้ฉันพบสิ่งที่ฉันต้องการได้รับการสนับสนุนและเข้าใจง่าย
นี่คือตัวอย่าง (ย่อ) จากหน้าแรกของ Mockito:
import static org.mockito.Mockito.*;
List mockedList = mock(List.class);
mockedList.clear();
verify(mockedList).clear();
มันไม่ง่ายไปกว่านั้นอีกแล้ว
ข้อเสียที่สำคัญอย่างเดียวที่ฉันคิดได้ก็คือมันจะไม่เลียนแบบวิธีการคงที่
ฉันเป็นผู้สร้าง PowerMock ดังนั้นแน่นอนว่าฉันต้องแนะนำ! :-)
PowerMockขยายทั้ง EasyMock และ Mockito ด้วยความสามารถในการจำลองวิธีแบบคงที่วิธีสุดท้ายและแบบส่วนตัว การสนับสนุน EasyMock เสร็จสมบูรณ์ แต่ปลั๊กอิน Mockito ต้องการการทำงานเพิ่มเติม เรากำลังวางแผนที่จะเพิ่มการสนับสนุน JMock เช่นกัน
PowerMock ไม่ได้มีวัตถุประสงค์เพื่อแทนที่เฟรมเวิร์กอื่น แต่สามารถใช้ในสถานการณ์ที่ยุ่งยากได้เมื่อเฟรมเวิร์กอื่นไม่อนุญาตการเยาะเย้ย PowerMock ยังมีคุณสมบัติที่มีประโยชน์อื่น ๆ เช่นการยับยั้ง initializers คงที่และตัวสร้าง
เว็บไซต์ของโครงการ JMockitมีความอุดมสมบูรณ์ของข้อมูลเปรียบเทียบสำหรับชุดเครื่องมือเยาะเย้ยปัจจุบัน
โดยเฉพาะให้ตรวจสอบเมทริกซ์การเปรียบเทียบคุณสมบัติซึ่งครอบคลุม EasyMock, jMock, Mockito, Unitils Mock, PowerMock และแน่นอน JMockit ฉันพยายามทำให้มันแม่นยำและทันสมัยมากที่สุด
ฉันได้รับการมีความสำเร็จกับJMockit
มันค่อนข้างใหม่และค่อนข้างดิบและมีเอกสารน้อย มันใช้ASMเพื่อกำหนดคลาสไบต์ใหม่แบบไดนามิกดังนั้นจึงสามารถจำลองวิธีการทั้งหมดรวมถึงแบบคงที่ส่วนตัวส่วนสร้างและแบบคงที่เริ่มต้น ตัวอย่างเช่น:
import mockit.Mockit;
...
Mockit.redefineMethods(MyClassWithStaticInit.class,
MyReplacementClass.class);
...
class MyReplacementClass {
public void $init() {...} // replace default constructor
public static void $clinit{...} // replace static initializer
public static void myStatic{...} // replace static method
// etc...
}
มันมีอินเตอร์เฟซที่คาดหวังช่วยให้สถานการณ์การบันทึก / เล่นเช่นกัน
import mockit.Expectations;
import org.testng.annotations.Test;
public class ExpecationsTest {
private MyClass obj;
@Test
public void testFoo() {
new Expectations(true) {
MyClass c;
{
obj = c;
invokeReturning(c.getFoo("foo", false), "bas");
}
};
assert "bas".equals(obj.getFoo("foo", false));
Expectations.assertSatisfied();
}
public static class MyClass {
public String getFoo(String str, boolean bool) {
if (bool) {
return "foo";
} else {
return "bar";
}
}
}
}
ข้อเสียคือต้องใช้ Java 5/6
คุณสามารถดูการทดสอบโดยใช้ Groovy ใน Groovy คุณสามารถจำลองการเชื่อมต่อ Java ได้อย่างง่ายดายโดยใช้ตัวดำเนินการ 'as':
def request = [isUserInRole: { roleName -> roleName == "testRole"}] as HttpServletRequest
นอกเหนือจากฟังก์ชั่นพื้นฐานนี้ Groovy ยังมีอีกมากที่ด้านหน้าเยาะเย้ยรวมถึงทรงพลังMockFor
และStubFor
คลาส
ผมเริ่มใช้ mocks กับEasyMock ง่ายต่อการเข้าใจ แต่ขั้นตอนการเล่นซ้ำนั้นค่อนข้างน่ารำคาญ Mockitoลบสิ่งนี้ออกไปและยังมีไวยากรณ์ที่สะอาดกว่าเนื่องจากดูเหมือนว่าการอ่านเป็นหนึ่งในเป้าหมายหลักของมัน ฉันไม่สามารถความเครียดได้เพียงพอความสำคัญนี้เนื่องจากนักพัฒนาซอฟต์แวร์ส่วนใหญ่จะใช้เวลาในการอ่านและบำรุงรักษาโค้ดที่มีอยู่ไม่ใช่สร้างมันขึ้นมา
สิ่งที่ดีอีกอย่างคืออินเทอร์เฟซและคลาสการใช้งานได้รับการจัดการในลักษณะเดียวกันแตกต่างจาก EasyMock ซึ่งคุณยังต้องจำ (และตรวจสอบ) เพื่อใช้ EasyMock Class Extension
เมื่อไม่นานมานี้ฉันได้ดูที่JMockitอย่างรวดเร็วและในขณะที่รายการคุณสมบัติซักรีดนั้นค่อนข้างครอบคลุมฉันคิดว่าราคาของรหัสนี้เป็นรหัสที่อ่านง่ายและต้องเขียนเพิ่มเติม
สำหรับฉัน Mockito ได้รับความนิยมเป็นอย่างมากเขียนและอ่านได้ง่ายและจัดการกับสถานการณ์ส่วนใหญ่ที่โค้ดส่วนใหญ่ต้องการ การใช้ MockitoกับPowerMockเป็นทางเลือกของฉัน
สิ่งหนึ่งที่ควรพิจารณาคือเครื่องมือที่คุณจะเลือกหากคุณกำลังพัฒนาด้วยตัวเองหรือในทีมที่รัดรูปขนาดเล็กอาจไม่ใช่วิธีที่ดีที่สุดสำหรับ บริษัท ขนาดใหญ่ที่มีนักพัฒนาที่มีระดับทักษะแตกต่างกัน ความสามารถในการอ่านความสะดวกในการใช้งานและความเรียบง่ายจะต้องพิจารณาเพิ่มเติมในกรณีหลัง ไม่มีเหตุผลในการรับกรอบการเยาะเย้ยที่สุดหากผู้คนจำนวนมากจบลงที่ไม่ได้ใช้มันหรือไม่ทำการทดสอบ
เราใช้EasyMockและ EasyMock Class Extension อย่างหนักในที่ทำงานและค่อนข้างมีความสุขกับมัน โดยทั่วไปจะให้ทุกสิ่งที่คุณต้องการ ดูเอกสารประกอบมีตัวอย่างที่ดีมากซึ่งแสดงคุณสมบัติทั้งหมดของ EasyMock
ฉันใช้ JMock เร็ว ฉันลอง Mockito ในโครงการสุดท้ายแล้วก็ชอบ รัดกุมยิ่งสะอาดยิ่งขึ้น PowerMock ครอบคลุมความต้องการทั้งหมดที่ขาดหายไปใน Mockito เช่นการเยาะเย้ยรหัสคงที่การเยาะเย้ยการสร้างอินสแตนซ์การเยาะเย้ยคลาสและวิธีการขั้นสุดท้าย ดังนั้นฉันมีทุกอย่างที่ฉันต้องการเพื่อทำงานของฉัน
ฉันชอบ JMock เพราะคุณสามารถตั้งค่าความคาดหวังได้ สิ่งนี้แตกต่างจากการตรวจสอบว่ามีการเรียกใช้วิธีการที่พบในห้องสมุดจำลองหรือไม่ ใช้ JMock คุณสามารถเขียนความคาดหวังที่ซับซ้อนมาก ดู jmock โกง sheat
ใช่ Mockito เป็นกรอบที่ยอดเยี่ยม ฉันใช้มันร่วมกับhamcrestและGoogle guiceเพื่อตั้งค่าการทดสอบของฉัน
ทางออกที่ดีที่สุดในการเยาะเย้ยคือการให้เครื่องทำงานทุกอย่างด้วยการทดสอบตามข้อกำหนดอัตโนมัติ สำหรับ Java ดูที่ScalaCheckและเฟรมเวิร์กReductio ที่รวมอยู่ในไลบรารีFunctional Java ด้วยเฟรมเวิร์กการทดสอบตามข้อกำหนดอัตโนมัติคุณจัดหาข้อมูลจำเพาะของวิธีการทดสอบ (คุณสมบัติที่ควรเป็นจริง) และเฟรมเวิร์กจะสร้างการทดสอบรวมถึงวัตถุจำลองโดยอัตโนมัติ
ตัวอย่างเช่นคุณสมบัติต่อไปนี้ทดสอบเมธอด Math.sqrt เพื่อดูว่าสแควร์รูทของจำนวนบวกใด ๆ n กำลังสองเท่ากับ n
val propSqrt = forAll { (n: Int) => (n >= 0) ==> scala.Math.sqrt(n*n) == n }
เมื่อคุณโทรpropSqrt.check()
ScalaCheck จะสร้างจำนวนเต็มเป็นร้อย ๆ และตรวจสอบคุณสมบัติของคุณสำหรับแต่ละรายการโดยอัตโนมัติเช่นกันเพื่อให้แน่ใจว่าเคสขอบได้รับการครอบคลุมอย่างดี
แม้ว่า ScalaCheck จะถูกเขียนใน Scala และต้องการ Scala Compiler มันเป็นเรื่องง่ายที่จะทดสอบโค้ด Java ด้วย เฟรมเวิร์ก Reductio ใน Functional Java เป็นการใช้งาน Java อย่างแท้จริงของแนวคิดเดียวกัน
Mockito ยังมีตัวเลือกของวิธีการขัดการจับคู่อาร์กิวเมนต์ (เช่น anyInt () และ anyString ()) เพื่อตรวจสอบจำนวนการร้องขอ (ครั้ง (3), atLeastOnce (), ไม่เคย ()) และอีกมากมายและอื่น ๆ
ฉันยังพบว่า Mockito นั้นเรียบง่ายและสะอาดเรียบง่ายและสะอาด
สิ่งหนึ่งที่ผมไม่ชอบเกี่ยวกับ Mockito คือการที่คุณไม่สามารถใช้วิธีการต้นขั้วแบบคงที่
ฉันเริ่มใช้ mocks ผ่าน JMock แต่ในที่สุดก็เปลี่ยนไปใช้ EasyMock EasyMock เป็นเช่นนั้นง่ายขึ้นและให้ไวยากรณ์ที่รู้สึกเป็นธรรมชาติมากขึ้น ฉันไม่ได้เปลี่ยนตั้งแต่