2

次のクラスがあるとしましょう(例外処理の削除など):

[ServiceBehavior(InstanceContextMode = ..., ConcurrencyMode = ..., etc)]
public class MyService : IMyService  
{
    ServiceReferenceMethodsHere....
}

public class HostStartup : IHostStartup
{
    private ServiceHost _myHost;

    public ServiceHost myHost
    {
       get { return _myHost; }
       set { _myHost= value; }
    }

    public void StartService(IMyService instance)
    {
        _myHost = new ServiceHost(instance);
    }

    public void StopService()
    }
        _myHost.Close();
    {
}

ServiceHost.Faulted次に、イベントにサブスクライブします。

// Note: Interfaces are registered via unity container and dependency injection.
// Unity bootstrapper class not shown. 
public class TestHost : ITestHost
{
    private IHostStartup _hostStartup;
    private IMyService _myService

    public TestHost(IHostStartup hostStartup, IMyService myService)
    {
        _hostStartup = hostStartup;
        _myService = myService;
        hostStartup.StartService(_myService);
        hostStartup.myHost.Faulted += HandleHostFault;
    }

    private void HandleHostFault(object sender, EventArgs e)
    {
        HandleFaultHere.....
    }
}

これで、イベントを処理するコードができましたServiceHost.Faulted。(もちろん、私のサービスを実際に機能させる他のすべての WCF ガッツを示したわけではありません...)

私の質問は、プライベート HandleHostFault メソッドをチートしてパブリックに設定せずに単体テストする方法です (私たちは皆、時々それをやりたいと思っています)。
つまり、ServiceHost.Faulted単体テスト環境でイベントを発生させることは可能ですか?

単体テストには NSubstitute を使用することを好みます。私は次のことを試しました:

private IHostStartup _hostStartup;
private IMyService _myService;
private TestHost _testHost;

public void MyTestInitialize()
{
    _hostStartup = Substitute.For<IHostStartup>();
    _myService = Substitute.For<IMyService>();
    _hostStartup.When(x => x.StartService(Arg.Any<IMyService>())).Do(x =>
                 {
                    _hostStartup.myHost = Substitute.For<ServiceHost>();
                 });
    _testHost  = new TestHost(_hostStartup, _myService);
}

public void HandleHostFault_InitializeHost_ServiceHostStatusOpen()
{
     // Arrange

     // Act
     hostStartup.myHost.Faulted += Raise.Event();


     // Assert
}

hostStartup.myHost.Faulted += Raise.Event()faulted イベントを発生させません。

この servicehost.faulted イベントを発生させる方法はありますか? 出来ますか?

** アップデート **

ServiceHost 通信オブジェクトを直接テストしないことにしました。「NSubstituteを使用してテストできない」と判断しました。HostStartup クラスから ServiceHost.Faulted イベントを処理するようになりました。

public class HostStartup : IHostStartup
{
    public event EventHandler<EventArgs> OnHostFault;

    public ServiceHost MyHost { get; private set; }

    public void StartService(IMyService instance)
    {
        MyHost = new ServiceHost(instance);
        MyHost.Faulted += HandleFault;
    }

    public void StopService()
    }
        _myHost.Close();
    {

    private void InvokeOnServiceHostFault(EventArgs eventArgs)
    {
        EventHandler<EventArgs> handler = OnHostFault;
        if (handler != null) handler(this, eventArgs);
    }

    private void HandleFault(object sender, EventArgs eventArgs)
    {
        InvokeOnServiceHostFault(eventArgs);
    }
}

// Note: Interfaces are registered via unity container and dependency injection.
// Unity bootstrapper class not shown. 
public class TestHost : ITestHost
{
    private IHostStartup _hostStartup;
    private IMyService _myService

    public TestHost(IHostStartup hostStartup, IMyService myService)
    {
        _hostStartup = hostStartup;
        _myService = myService;
        hostStartup.StartService(_myService);
        hostStartup.OnHostFault += HandleHostFault;
    }

    private void HandleHostFault(object sender, EventArgs e)
    {
        HandleFaultHere.....
    }
}

そして最後に、ユニットテストアクションはうまく機能します:

public void HandleHostFault_InitializeHost_ServiceHostStatusOpen()
{
     // Arrange

     // Act
     hostStartup.OnHostFault += Raise.Event();  // works great!! :)


     // Assert
}
4

1 に答える 1

0

PrivateObject クラスを使用して、クラスのプライベート メンバーを単体テストできます。説明と例については、以下のリンクを参照してください

http://msdn.microsoft.com/en-us/library/bb546207.aspx

于 2012-10-05T01:31:28.850 に答える