2017-05-03 11 views
3

ASMXサービスを使用してsmsを送信するWebアプリケーションがありますが(現在は生産中で、正常に動作しています)、今は単体テストこの出願はしたがって、このアクションメソッドは、パラメータとして、ビューモデルを受信moqを使用して.NETでasmxサービスを使用するアプリケーションをテストする方法

public ActionResult CreateSms(SendSMSViewModel tblSend) 
{ 
    if (ModelState.IsValid) 
    { 
     if (_dbManager.SendSMS(tblSend.CellNumber, tblSend.Message, User.Identity.Name)) 
     { 
      TempData["Success"] = "Message was successfully sent"; 
     } 
     else 
     { 
      TempData["Error"] = "An error occured while sending the message"; 
     } 
    } 

    return RedirectToAction("CreateSms"); 
} 

、このvmodel 2つの特性(細胞数、メッセージ)を有している私は、ユニットテストに興味がある特定のアクションの方法で以下、ASMXサービスを消費しSMSを送信しているユーザーもいます。今私のユニットテストや統合に私は次のコードを、私は以下の方法(複数可)

public DatabaseManagerTest() 
{ 
    Mock<IDatabaseManager> moqDB = new Mock<IDatabaseManager>(); 

    //Setup send sms test 
    moqDB.Setup(md => md.SendSMS("0734233173", "Test message", "Ronny.Mahlangu")).Returns(true); 

    this._mockDatabaseManager = moqDB.Object; 
} 

を模擬しようとしています。この最初の部分は、実際のテストできた(謝罪私はまた2を混乱させるために起こります)方法

public void TestSendSms() 
{ 
    bool results = this._mockDatabaseManager.SendSMS("0734233173", "Test message", "Ronny.Mahlangu"); 
    Assert.IsTrue(results); 
} 

私のテストでは、このケースでは、私は唯一のSMSは、私はアクションメソッド自体をテスト行くのですか、首尾よく送信するかどうかをテストしています、しかし、私はまた、ユニットテストにアクションメソッド自体をしたい、渡すように見えます確かに私はasmxサービスを模擬する必要がありますが、私は空白です

またSendSMS方法はASMXメソッドが呼び出されているところであるDatabaseManagerという名前のクラスから来て、ここではそのクラスからのコードの平和

public bool SendSMS(string cellNumber, string message, string logonName) {  
    if(string.IsNullOrWhiteSpace(cellNumber)) 
    { 
     throw new ArgumentNullException("cell phone number is null"); 
    } 
    if(string.IsNullOrWhiteSpace(message)) 
    { 
     throw new ArgumentNullException("Sms message is null"); 
    } 

    using (SMSService.SendSmsSoapClient sms = new SMSService.SendSmsSoapClient()) 
    { 
     if (sms.SendDirect(cellNumber, message, ConfigurationManager.AppSettings["costCentre"], userLogonName, ConfigurationManager.AppSettings["source"]) == SMSService.Status.Successful) 
     { 
      SaveSmsDetails(cellNumber, message, userLogonName); 
      return true; 
     } 
    } 

    return false; 
} 

答えて

2

DatabaseManagerは、第三のラップコントローラの依存性であることに注意asmxサービスへの部分呼び出し。最初のテストでは実際にモックをテストしていますがあまり使用されていません。コントローラーをテストするには、アクションが完了するまでに必要な依存関係を提供する必要があります。

ここは簡単な例です。問題の元の例に基づいて、次のインタフェースを仮定

..

public interface IDatabaseManager { 
    bool SendSMS(string cellNumber, string message, string logonName); 
} 

以下は、この例では、被試験コントローラを表す

public class SmsController : Controller { 
    private IDatabaseManager _dbManager; 

    public SmsController(IDatabaseManager databaseManager) { 
     this._dbManager = databaseManager; 
    } 


    public ActionResult CreateSms(SendSMSViewModel tblSend) { 
     if (ModelState.IsValid) { 
      if (_dbManager.SendSMS(tblSend.CellNumber, tblSend.Message, User.Identity.Name)) { 
       TempData["Success"] = "Message was successfully sent"; 
      } else { 
       TempData["Error"] = "An error occured while sending the message"; 
      } 
     } 

     return RedirectToAction("CreateSms"); 
    } 
} 

試験に使用依存関係をモック必要とするアクションアクション。以下はどのようにそれを行うことができるかを示しています。

[TestMethod] 
public void TestCreateSms() { 
    //Arrange 
    var expectedCellNumber = "0734233173"; 
    var expectedMessage = "Test message"; 
    var expectedName = "Ronny.Mahlangu"; 
    var expectedResult = true; 

    // - dependency mocked with desired behavior 
    var moqDB = new Mock<IDatabaseManager>(); 
    moqDB 
     .Setup(md => md.SendSMS(expectedCellNumber, expectedMessage, expectedName)) 
     .Returns(expectedResult) 
     .Verifiable(); 

    // - Fake user for request in order to access User.Identity.Name 
    var principal = new ClaimsPrincipal(new GenericIdentity(expectedName)); 
    var contextMock = new Mock<HttpContextBase>(); 
    contextMock.Setup(_ => _.User).Returns(principal); 

    // - controller under test 
    var controller = new SmsController(moqDB.Object); 
    controller.ControllerContext = new ControllerContext(contextMock.Object, new RouteData(), controller); 

    // - view model sent to action 
    var tblSend = new SendSMSViewModel { 
     CellNumber = expectedCellNumber, 
     Message = expectedMessage 
    }; 

    //Act 
    var result = controller.CreateSms(tblSend); 

    //Assert 
    moqDB.Verify(); //verify that the mock executed as expected 
    //you can also assert the results of calling the action to confirm expectations 
    Assert.IsTrue(controller.TempData.ContainsKey("Success")); 
    Assert.IsInstanceOfType(result, typeof(RedirectToRouteResult)); 
    var redirectResult = result as RedirectToRouteResult; 
    Assert.AreEqual("CreateSms", redirectResult.RouteValues["action"]); 
} 

上記コピーされ、単にモック依存リターンfalseことにより、SendSMSが失敗した場合のように、他のシナリオをテストするために修飾することができます。

これで十分です。

関連する問題