سؤال

أحاول كتابة اختبار وحدة C # مع إطار اختبار الوحدة المدمج في وحدة VS 2008 وطريقة اختبار المكالمات Environment.Exit(0). وبعد عندما أسمي هذه الطريقة في اختبار الوحدة الخاص بي، يتم إحباط اختبار وحدتي. يجب أن تكون الطريقة دعوة بالفعل Exit, وأريد طريقة لاختبار أنها تفعل ذلك، وكذلك لاختبار رمز الخروج الذي يستخدمه. كيف يمكنني القيام بذلك؟ نظرت إلى microsoft.visualstudio.testtools.unittesting اسم الاسم ولكن لم ير أي شيء بدا ذات صلة.

[TestMethod]
[DeploymentItem("myprog.exe")]
public void MyProgTest()
{
    // Want to ensure this Exit's with code 0:
    MyProg_Accessor.myMethod();
}

وفي الوقت نفسه، هنا هو GIST من التعليمات البرمجية التي أريد اختبارها:

static void myMethod()
{
    Environment.Exit(0);
}

يحرر: إليك الحل الذي استخدمته في طريقة الاختبار الخاصة بي، بفضل ريتشاردود:

Process proc;

try
{
    proc = Process.Start(path, myArgs);
}
catch (System.ComponentModel.Win32Exception ex)
{
    proc = null;
    Assert.Fail(ex.Message);
}

Assert.IsNotNull(proc);
proc.WaitForExit(10000);
Assert.IsTrue(proc.HasExited);
Assert.AreEqual(code, proc.ExitCode);
هل كانت مفيدة؟

المحلول

هذا يبدو وكأنه فكرة سيئة بشكل لا يصدق. البيئة.exit (0)، سوف تفعل بوضوح كما هو محدد، وبالتالي لماذا لا تحطم وحدات الخاص بك.

إذا كنت تريد حقا أن تظل اختبار هذا، فيمكنك تشغيل عملية منفصلة والتحقق من رمز الإرجاع - إلقاء نظرة على التفاف process.start..

أعتقد أن خيار آخر هو عامل هذا الرمز وقم بحقن اختبار تجسس, ، أو استخدام كائن وهمية للتحقق من السلوك الصحيح.

ربما يمكنك أن تفعل شيئا مع معزول Typemock - أعتقد أن هذا يتيح لك الأساليب الساكنة وهمية.

نصائح أخرى

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

public class EnvironmentWrapper
{
    public virtual void Exit( int code )
    {
        Environment.Exit( code );
    }
}


public class MyClass
{
    private EnvironmentWrapper Environment { get; set; }

    public MyClass() : this( null ) { }

    public MyClass( EnvironmentWrapper wrapper )
    {
        this.Environment = wrapper ?? new EnvironmentWrapper();
    }

    public void MyMethod( int code )
    {
        this.Environment.Exit( code )
    }
}


[TestMethod]
public void MyMethodTest()
{
     var mockWrapper = MockRepository.GenerateMock<EnvironmentWrapper>();

     int expectedCode = 5;

     mockWrapper.Expect( m => m.Exit( expectedCode ) );

     var myClass = new MyClass( mockWrapper );

     myclass.MyMethod( expectedCode );

     mockWrapper.VerifyAllExpectations()
}

لن تكون قادرا على اختبار هذا - Environment.Exit يقتل التطبيق تماما. هذا يعني أنه سيتم تفريغ أي تطبيق Appdomain الذي يستخدم هذا الرمز تماما، سواء كان تطبيق الإنتاج الخاص بك أو إطار اختبار الوحدة.

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

يمكنك إضافة حجة إلى طريقتك لتمريرها بيئة مزيفة حيث لن يتم إنهاء طريقة الخروج ().

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

الشيء الوحيد الذي يأتي إلى ذهني شيء جنبا إلى جنب:

static void myMethod()
{
    DoEnvironmentExit(0);
}

static void DoEnvironentExit(int code)
{
    #if defined TEST_SOLUTION
      SomeMockingFunction(code);
    #else
      Environment.Exit(code);
    #endif
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top