2017-05-03 2 views
3

현재 ASMX 서비스를 사용하여 sms를 보내는 웹 응용 프로그램이 있습니다. 그러나 이제는 단위 테스트가 필요합니다. 이 응용 프로그램은 다음과 나는 그래서이 작업 방법은 매개 변수로 뷰 모델을 수신 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; 
} 

을 조롱하려고 노력하고 있어요 첫 번째 부분은 실제 시험 인 한 (사과 나 또한 두 가지를 혼동하는 일이) 방법

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에서 코드의 평화는 3 랩 컨트롤러의 종속성입니다 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가 실패 할 때와 같은 다른 시나리오를 테스트하기 위해 수정 될 수있다.

시작하기에 충분합니다.