2011-09-09 10 views
4

私は本当に気分が悪いです。電子メールを送信して新しいスレッドを作成するユニットテスト

通知用の電子メールを送信するWebアプリケーションが1つあります。

それは、このような電子メールを送信し、基本的なメソッドを含むクラスです。

MailMessage email = new MailMessage(); 

     email.To.Add("[email protected]"); 

     email.Subject = "Test"; 
     email.Body = "t"; 

     SmtpClient client = new SmtpClient(); 

     client.Send(email); 

が、私はそれはいくつかのロジックを検証NotificatorServiceというサービスがあり、これはちょうど「余分な」方法であるため、私はNotificatorServiceをインスタンス化するユニット・テストを作成していない呼び出す場合

public void NotifyMembers(NotificatorClientDTO clientDto) { 
if(clientDto == null) 
    throw new ArgumentNullException("clientDto"); 


Thread t = new Thread( 
    () => { 
    // go to database, verify business rules, etc... 

    // At the end if it is ok, invoke the method that sends a email 
} 

t.Start() 

}

:このサービスのために私は何をすると、この..です新しいスレッドで呼び出されますいくつかのデータを持つtifyMembersでは、コードは例外をスローしますが、私が別のスレッドで実行する場合に限ります。

私が作成したスレッドはforegronndに設定されているので、システムは自分のプロセスを破壊しないと思います。コードが最適化されたまたはネイティブフレームがコールスタックの一番上にあるされているので、私は2つのインナー例外に歩い

式を評価することができませんし、私はこれを参照してください。

SmtpException:

例外メッセージはこれです

_message "スレッドが中止されました。"文字列

どうしたのですか? 何が原因でスレッドが中止されますか?

+0

は、このテストは任意のUI層コンポーネントの呼び出しが含まれますか?場合によっては、テストアセンブリの設定でMTA appartmentの状態を指定する価値があります – sll

+0

メインスレッドをブロックしたくないので、サービスは新しいスレッドを作成します。このスレッド(デーモンを作成するスレッド)は実行され、クライアントに表示するビューをレンダリングするMVCアプリケーションに戻ります。 – anotherNeo

+0

UIレベルがあると思われるので、用意したスニペットを使ってNUNitスレッドのAppartmentStateを変更しようとしましたか? – sll

答えて

2

ユニットテストを変更して、IMailServiceまたはそれに類するものを使用してください。その後、あなたのウェブアプリケーションユニットのテストは何もする必要はありません電子メールの送信の点で - それは偽物やモックを使用することができます。

あなたはその後、コースのIMailServiceの生産の実装を作成する必要があります - あなたがかもしれ意味し、はまだ挑戦的かもしれないが、少なくともあなたはその後、メール処理のテストにのみ興味だろうということと、ユニットテスト制約をいくらか変更することができます。

物事のスレッド作成側で同じことを行う可能性があります。基本的には、テストしたい実際のロジックからコード(メールサービスやスレッドとやりとりする)の「不快なビット」を分離してみてください。

1

質問タイトルで指定したように、ユニットテストではなく統合テストのように見えます。

次の内容のTests.AssemblyプロジェクトにApp.configファイルを追加し、それが助けかどうかを確認するために試してみてください:(ApartmentState=MTA and ApartmentState=STAで遊ぶ)

<?xml version="1.0" encoding="utf-8"?> 

<configuration> 
    <configSections> 
     <sectionGroup name="NUnit"> 
      <section name="TestRunner" type="System.Configuration.NameValueSectionHandler"/> 
     </sectionGroup> 
    </configSections> 

    <NUnit> 
     <TestRunner> 
      <add key="ApartmentState" value="STA" /> 
     </TestRunner> 
    </NUnit> 
</configuration> 
関連する問題