仕事始め(2)

年始早々のテストコードについて、続き(・∀・)


テスト対象のライブラリ内に、例外発生時にその場でcatchしてMessageBoxを表示している所がある問題について。
下層のライブラリ内がこんなコードになっていて(゚Д゚)

try
{
...
}
catch(HogeException e)
{
    LogError( "Exxx" );  // この中でMessageBoxを表示

    throw;
}

ちなみに、Application.ThreadExceptionは別に設定してあって、そちらでもメッセージボックスを表示するようになっているんですけどね(´Д`)


で、自動テストを作ってみたものの、例外になるケースでは、メッセージボックスの表示によりテストが止まってしまうという罠。


調べてみたら、MessageBoxButtons.OKなMessageBoxしか表示していない、つまりエラーの通知だけだったので、MessageBoxの表示時にはフックして自動的に閉じるようにしてみたり(´Д`)
コールバックするdelegateとSetWindowsHookEx()の戻り値を保持するWindowsHookクラスを用意して、こんな感じの処理にしてみました。

private const UInt32 WM_CLOSE = 0x0010;

[DllImport("user32.dll", SetLastError=true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool PostMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);

private static WindowsHook hook;

public void Test()
{
    using( hook = new WindowsHook( WindowsHook.WH_CBT,
                                   new WindowsHook.HookProc( CBTProc ),
                                   IntPtr.Zero,
                                   AppDomain.GetCurrentThreadId() ) )
    {
        ...(テスト対象の呼び出し)
    }
}

public static IntPtr CBTProc(int nCode, IntPtr wParam, IntPtr lParam)
{
    if ( nCode == WindowsHook.HCBT_ACTIVATE )
    {
        // メッセージボックス強制クローズ
        PostMessage( wParam, WM_CLOSE, IntPtr.Zero, IntPtr.Zero );

        return( IntPtr.Zero );
    }

    return( hook.CallNextHook( nCode, wParam, lParam ) );
}

MessageBoxが表示される時にはWM_CLOSEを送って、自動でクローズするようにしているって事です(´Д`;)


とりあえず、そんなんで無理矢理にテストを自動化してみたり(´ω`)