سؤال

نحن نستخدم الربيع بطلب أغراض الربيع اختبار إطار وحدة الاختبارات.لدينا مشكلة صغيرة على الرغم من:تطبيق كود الأحمال الربيع سياق التطبيق من قائمة المواقع (ملفات xml) في classpath.ولكن عندما نقوم بتشغيل الوحدة الاختبارات نريد بعض من الفاصوليا الربيع أن يسخر بدلا من كامل تنفيذ الطبقات.علاوة على ذلك, بعض وحدة الاختبارات نريد بعض الفاصوليا إلى أن تصبح يسخر ، في حين أن وحدة أخرى الاختبارات نريد حبوب أخرى لتصبح يسخر كما نحن اختبار طبقات مختلفة من التطبيق.

كل هذا يعني أريد أن تعريف محدد الفاصوليا من سياق تطبيق وتحديث السياق عندما المطلوب.حين نفعل ذلك, أريد أن تعريف سوى جزء صغير من الفول يقع في واحدة (أو عدة) xml الأصلي الفاصوليا ملف تعريف.وأنا لا يمكن العثور على وسيلة سهلة للقيام بذلك.انها تعتبر دائما أن الربيع هو اختبار وحدة ودية إطار ذلك يجب أن يكون في عداد المفقودين على شيء هنا.

هل لديك أي أفكار كيف نفعل ذلك ؟

شكرا

هل كانت مفيدة؟

المحلول

أود أن أقترح TestClass مخصص وبعض القواعد السهلة لمواقع The Spring Bean.xml

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
    "classpath*:spring/*.xml",
    "classpath*:spring/persistence/*.xml",
    "classpath*:spring/mock/*.xml"})
@Transactional
@TestExecutionListeners({
    DependencyInjectionTestExecutionListener.class,
    TransactionalTestExecutionListener.class,
    DirtiesContextTestExecutionListener.class})
public abstract class AbstractHibernateTests implements ApplicationContextAware 
{

    /**
     * Logger for Subclasses.
     */
    protected final Logger LOG = LoggerFactory.getLogger(getClass());

    /**
     * The {@link ApplicationContext} that was injected into this test instance
     * via {@link #setApplicationContext(ApplicationContext)}.
     */
    protected ApplicationContext applicationContext;

    /**
     * Set the {@link ApplicationContext} to be used by this test instance,
     * provided via {@link ApplicationContextAware} semantics.
     */
    @Override
    public final void setApplicationContext(
            final ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }
}

إذا كان هناك mock-bean.xml في الموقع المحدد، فسيتم تجاوز كل "حقيقي" bean.xml في المواقع "العادية" - قد تختلف مواقعك العادية

ولكن ... لن أقوم بمزيج الفاصوليا غير المساواة ولا يصعب تتبع المشاكل، عندما ينمو التطبيق أكبر.

نصائح أخرى

واحدة من الأسباب الربيع يوصف اختبار الصديقة لأنه قد يكون من السهل فقط جديد أو تسخر من الاشياء في اختبار الوحدة.

بالتناوب لدينا تستخدم الإعداد التالية بنجاح كبير, و أعتقد أنها قريبة جدا من ما أردت أن بقوة يوصي هذا:

لجميع الفاصوليا التي تحتاج إلى تطبيقات مختلفة في سياقات مختلفة ، والتحول إلى الشرح القائمة على الأسلاك.يمكنك ترك الآخرين كما هو.

تنفيذ ما يلي مجموعة من الشروح

 <context:component-scan base-package="com.foobar">
     <context:include-filter type="annotation" expression="com.foobar.annotations.StubRepository"/>
     <context:include-filter type="annotation" expression="com.foobar.annotations.TestScopedComponent"/>
     <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
 </context:component-scan>

ثم علق الخاص بك يعيش تطبيقات مع @مستودع ، كعب تطبيقات مع @StubRepository أي البرمجية التي يجب أن تكون موجودة في وحدة المباراة اختبار فقط مع @TestScopedComponent.يجوز لك تشغيل في الحاجة إلى المزيد من الشروح ، ولكن هذه هي بداية رائعة.

إذا كان لديك الكثير من spring.xml, وربما كنت سوف تحتاج إلى إجراء بضع ربيع جديد ملفات xml هذا الأساس فقط تحتوي على عنصر المسح التعاريف.كنت عادة فقط إلحاق هذه الملفات العادية @ContextConfiguration قائمة.والسبب في ذلك هو لأنك في كثير من الأحيان في نهاية المطاف مع تكوينات مختلفة من السياق-المسح (ثق بي ، سوف جعل ما لا يقل عن 1 أكثر الشروح إذا كنت تفعل شبكة الإنترنت الاختبارات ، مما يجعل لمدة 4 ذات الصلة مجموعات)

ثم أساسا استخدام

@ContextConfiguration(locations = { "classpath:/path/to/root-config.xml" })
@RunWith(SpringJUnit4ClassRunner.class)

لاحظ أن هذا الإعداد لا لا تسمح لك أن يكون بالتناوب مجموعات من كعب/بيانات حية.حاولنا هذا, وأعتقد أن هذا أدى إلى حالة من الفوضى لا أنصح أي شخص ;) اما سلك inn مجموعة كاملة من بذرة أو مجموعة كاملة من الخدمات الحية.

ونحن نستخدم بشكل رئيسي السيارات السلكية كعب تبعيات عند اختبار واجهة المستخدم الرسومية بالقرب من الاشياء حيث تبعيات عادة ما تكون كبيرة جدا.في نظافة المناطق من قانون نستخدم أكثر انتظاما وحدة الاختبار.

في نظامنا لدينا ما يلي ملفات xml على عنصر المسح:

  • على الويب العادية الإنتاج
  • لبدء ويب مع بذرة فقط
  • من أجل التكامل الاختبارات (في junit)
  • من أجل وحدة الاختبارات (في junit)
  • على السيلينيوم ويب الاختبارات (في junit)

هذا يعني أننا تماما 5 مختلفة على نطاق المنظومة تكوينات نتمكن من بدء التطبيق مع.منذ نحن فقط استخدام الشروح الربيع هو سريع بما فيه الكفاية autowire حتى أولئك وحدة الاختبارات نريد السلكية.أنا أعلم أن هذا غير تقليدية ، ولكن انه لشيء رائع حقا.

خارج التكامل اختبارات تشغيل مع كامل الإعداد الحية ، مرة أو مرتين كنت قد قررت الحصول على حقا واقعية و تريد أن يكون لديك 5 تعيش التمديدات واحد وهمية:

public class HybridTest {
   @Autowired
   MyTestSubject myTestSubject;


   @Test
   public void testWith5LiveServicesAndOneMock(){
     MyServiceLive service = myTestSubject.getMyService();
     try {
          MyService mock = EasyMock.create(...)
          myTestSubject.setMyService( mock);

           .. do funky test  with lots of live but one mock object

     } finally {
          myTestSubject.setMyService( service);
     }


   }
}

أعلم الاختبار الأصوليون ستكون كل هذا.ولكن في بعض الأحيان انها مجرد حل عملي جدا أن تتحول إلى أن تكون أنيقة جدا عندما يكون البديل حقا حقا قبيحة.مرة أخرى أنها عادة ما تكون في واجهة المستخدم الرسومية-بالقرب من المناطق.

انظر الى هذا البرنامج التعليمي مع AInjectedMock

أنقذني الكثير من الوقت. أنت فقط تستخدم

@Mock
SomeClass mockedSomeClass

@InjectMock
ClassUsingSomeClass service

@Before
public void setUp() {
    MockitoAnnotations.initMocks(this);
}

وجميع مشاكلك يتم حلها. سوف يحل mockito محل حقن الربيع التبعية مع وهمية. أنا فقط استخدمها بنفسي وهي تعمل بشكل رائع.

هناك بعض الحلول المعقدة للغاية والقوية المدرجة هنا.

ولكن هناك بعيدا، أبسط بكثير طريقة لإنجاز STAS قد طلبت، والتي لا تنطوي على تعديل أي شيء آخر غير سطر التعليمات البرمجية في طريقة الاختبار. إنه يعمل من أجل اختبارات الوحدات واختبارات تكامل الربيع على حد سواء، للتبعية المتنقلة والحقول الخاصة والحماية.

ها هو:

junitx.util.PrivateAccessor.setField(testSubject, "fieldName", mockObject);

يمكنك أيضا كتابة اختبارات الوحدة الخاصة بك لا تتطلب أي عمليات بحث على الإطلاق:

@ContextConfiguration(locations = { "classpath:/path/to/test-config.xml" })
@RunWith(SpringJUnit4ClassRunner.class)
public class MyBeanTest {

    @Autowired
    private MyBean myBean; // the component under test

    @Test
    public void testMyBean() {
        ...
    }
}

هذا يعطي طريقة سهلة لخلط وتطابق ملفات التكوين الحقيقية مع ملفات تكوين الاختبار.

على سبيل المثال، عند استخدام السبات، قد يكون لدي فاصوليا للدرحين في ملف تكوين واحد (لاستخدامه في كل من الاختبارات والتطبيق الرئيسي)، ولديه فاصول DataSource في ملف تكوين آخر (قد يستخدم المرء أداة درجينغر DrivermanagerDatasource إلى الذاكرة DB، والآخر قد يستخدم البحث عن JNDI).

ولكن، بالتأكيد استسلام @ كليتوس تحذير ؛-)

سهل. يمكنك استخدام سياق تطبيق مخصص لاختبارات الوحدة الخاصة بك. أو أنت لا تستخدم واحدة على الإطلاق وأنت تقوم بإنشاء وحقن حبوبك يدويا.

يبدو لي مثل الاختبار قد يكون واسع جدا جدا. اختبار الوحدة يدور حول الاختبار، حسنا، وحدات. فاصوليا الربيع مثال جيد جدا على وحدة. يجب أن لا تحتاج إلى سياق تطبيق كامل لذلك. أجد أنه إذا كان اختبار الوحدة الخاص بك هو مستوى عال جدا، فأنت بحاجة إلى مئات الفاصوليا واتصالات قاعدة البيانات وما إلى ذلك ثم لديك اختبار وحدة هشة حقا سيقتحم في التغيير التالي جدا، وسيكون من الصعب الحفاظ عليه وحقا " إضافة الكثير من القيمة.

يمكنك استعمال ال يستورد ميزة في سياق تطبيق الاختبار الخاص بك لتحميل في الفاصوليا Prod وتجاوز تلك التي تريدها. على سبيل المثال، يتم الحصول على مصدر بيانات Prod الخاص بي عادة عبر بحث JNDI، ولكن عندما أقوم باختبار استخدام مصدر بيانات Drivermanager لذلك ليس علي بدء تشغيل خادم التطبيقات.

ليس لدي نقاط سمعة كومة على إجابة Duffymo، لكنني أردت فقط أن تتناغم وتقول إنها كانت الإجابة "الصحيحة" بالنسبة لي.

Instantiate FileSystemXMLApplicationContext في إعداد اختبار الوحدة الخاص بك مع تطبيق مخصص CompmentContext.xml. في هذا XML مخصص، في الأعلى، كما يشير duffymo. ثم أعلن الفاصوليا الخاصة بك، مصادر البيانات غير JNDI، إلخ، من شأنها أن تتجاوز المعرف المعلن في الاستيراد.

عملت مثل الحلم بالنسبة لي.

لا تحتاج إلى استخدام أي سياقات اختبار (لا يهم XML أو Java مقرها). منذ الحذاء الربيعي 1.4 هناك شرح جديد متاح @MockBean التي قدمت الدعم الأصلي للسخرية والتجسس من حبوب الربيع.

ربما يمكنك استخدام التصفيات للفاصوليا الخاصة بك؟ كنت ترغب في إعادة تعريف الفاصوليا التي تريد أن تسخر منها في سياق تطبيق منفصل وتسميها مع "اختبار" مؤهل. في اختبارات الوحدة الخاصة بك، عندما تحدد الأسلاك الفول الخاصة بك دائما "اختبار" التصفيات لاستخدام UPS وهمية.

أريد أن أفعل الشيء نفسه، ونجد أنه من الضروري.

الآلية الحالية التي نستخدمها هي دليل إلى حد ما ولكنها تعمل.

قل على سبيل المثال، ترغب في خروج الفول من النوع Y. ما نفعله هو كل فول له تلك التبعية التي نجعلها تنفذ واجهة - "Ihasy". هذه الواجهة

interface IHasY {
   public void setY(Y y);
}

ثم في الاختبار لدينا نسمي طريقة Util ...

 public static void insertMock(Y y) {
        Map invokers = BeanFactory.getInstance().getFactory("core").getBeansOfType(IHasY.class);
        for (Iterator iterator = invokers.values().iterator(); iterator.hasNext();) {
            IHasY invoker = (IHasY) iterator.next();
            invoker.setY(y);
        }
    }

لا أريد إنشاء ملف XML كامل فقط لحقن هذا التبعية الجديدة وهذا هو السبب في أنني أحب هذا.

إذا كنت على استعداد لإنشاء ملف تكوين XML، فستكون الطريقة للذهاب هي إنشاء مصنع جديد مع فاصوليا وهمية وجعل المصنع الافتراضي الخاص بك أحد المصنع. تأكد من تحميل جميع فاصوليا من مصنع الطفل الجديد. عند القيام بذلك، سيتجاوز المصنع الفرعي الفاصوليا في المصنع الأم عندما تكون معرف الفول نفسه.

الآن إذا، في اختباري، إذا استطعت برمجيا إنشاء مصنع، سيكون ذلك رائعا. الاضطرار إلى استخدام XML هو مجرد مرهقة للغاية. أنا أتطلع إلى إنشاء مصنع الطفل مع التعليمات البرمجية. ثم كل اختبار يمكن أن تكوين مصنعه بالطريقة التي تريدها. لا يوجد سبب يجعل المصنع مثل هذا لن يعمل.

الربيع سحر مصممة لاستبدال الفاصوليا مع السخرط.

منذ المرجع هذا جاء جنبا إلى جنب: splingockito.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top