سؤال

والدب معي، وأنا جديدة على NUnit. لقد جئت من أرض القضبان، وحتى بعض من هذا هو الجديد بالنسبة لي.

ولقد سطر من التعليمات البرمجية التي تبدو مثل هذا:

var code = WebSiteConfiguration.Instance.getCodeByCodeNameAndType("CATALOG_Brands_MinQty", item.Catalog);

وأنا أحاول أن يسخر منه، مثل هذا (تفترض تتم تهيئة code بالفعل):

var _websiteConfigurationMock = new DynamicMock(typeof(WebSiteConfiguration));
_websiteConfigurationMock.ExpectAndReturn("getCodeByCodeNameAndType", code);

عند I تصحيح الاختبار، getCodeByCodeNameAndType تعود null، بدلا من code المتوقع. ما أفعل الخطأ؟

وNUnit النسخة: 2.2.8

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

المحلول

وA DynamicMock بإنشاء كائن جديد في الذاكرة التي تمثل واجهة، أو marshallable (يرث من MarshalByRef) فئة تريد أن يسخر.

وجرب هذا:

var _websiteConfigurationMock = new DynamicMock(typeof(WebSiteConfiguration));
_websiteConfigurationMock.ExpectAndReturn("getCodeByCodeNameAndType", code);
WebSiteConfiguration conf = (WebSiteConfiguration)_websiteConfigurationMock.MockInstance;
var x = conf.getCodeByCodeNameAndType("CATALOG_Brands_MinQty", item.Catalog);

لاحظ أن السطر الثالث هناك لن تنجح ما لم يرث WebSiteConfiguration من MarshalByRef.

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

نصائح أخرى

وأنا آسف، ولكن أنا لم تستخدم NUnit.Mocks - ولكن لدي بعض الخبرة في NMock وموك [الذي، بالمناسبة، أنا أوصي]. عادة، يمكنك استخدام مكتبة ساخرا لتوليد وكلاء للحصول على تعريفات واجهة، وأفترض NUnit.Mocks تعمل بنفس الطريقة.

لذلك، إذا كنت ترغب في أن يسخر المفرد الخاص بك، سيكون لديك على الأرجح إلى القيام بما يلي،

أ. إنشاء واجهة، ويقول

// All methods you would like to mock from this class, should 
// be members of this interface
public interface IWebSiteConfiguration
{
    // Should match signature of method you are mocking
    CodeType getCodeByCodeNameAndType (
        string codeString, 
        CatalogType catalogType);
}

ب. "تنفيذ" واجهة

// You've already written the method, interface matches signature,
// should be as easy as slapping interface on class declaration
public class WebSiteConfiguration : IWebSiteConfiguration { }

وج. تستهلك اجهة

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

وكان

public class MyClass
{
    public MyClass () { }

    public void DoSomething ()
    {
        // bad singleton! bad boy! static references are bad! you
        // can't change them! convenient but bad!
        code = WebSiteConfiguration.Instance.getCodeByCodeNameAndType (
            "some.string", 
            someCatalog)
    }
}

ويصبح

public class MyClass
{
    private readonly IWebSiteConfiguration _config = null;

    // just so you don't break any other code, you can default
    // to your static singleton on a default ctor
    public MyClass () : this (WebSiteConfiguration.Instance) { }

    // new constructor permits you to swap in any implementation
    // including your mock!
    public MyClass (IWebSiteConfiguration config) 
    {
        _config = config;
    }

    public void DoSomething ()
    {
        // huzzah!
        code = _config.getCodeByCodeNameAndType ("some.string", someCatalog)
    }
}

في اختبار وحدتك، وخلق وهمية، لتمرير إشارة من وهمية للمستهلك، واختبار المستهلك.

[Test]
public void Test ()
{
    IWebSiteConfiguration mockConfig = null;
    // setup mock instance and expectation via
    // NUnit.Mocks, NMock, or Moq

    MyClass myClass = new MyClass (mockConfig);
    myClass.DoSomething ();

    // verify results
}

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

ويساعد هذا الأمل:)

ويبدو أن هناك نوعا من الحل لهذا التفكير به، أو ربما أنا يساء فهمه تماما هذا.

ويتم مناقشتها هنا: HTTP: //www.geekbeing كوم / 2010 / 23/05 / كيف لوحدة اختبار المفرد-الإختراق في وج

ويمكن أن يعمل حقا؟

public class TestableSingleton : SingletonClass
{
  public TestableSingleton ()
  {
    FieldInfo fieldInfo = typeof(SingletonClass)
        .GetField("_instance",
        BindingFlags.Static | BindingFlags.NonPublic);
    fieldInfo.SetValue(Instance, this);
  }
}

وتلتقطها مشروع https://github.com/rbabreu/TestableSingleton

والحقيقة لم أستطع ترجمة ذلك على Visual ستوديو منذ SingletonClass سيكون له منشئ الخاص. اذا كان شخص ما الحصول على العمل ستكون كبيرة لتجنب الحمل من نمط محول.

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