2016-02-04 5 views
2

Я пытаюсь написать модульный тест в проекте Visual C# Unit Test.Как протестировать метод Action, который принимает массив объекта и возвращает JsonResult в ASP.Net MVC

Пропускаю пустой Array из Кадр класс, который возвращает объект JSON.

[HttpPost] 
    public JsonResult SubmitBowlingScore(Frame[] frames) 
    { 
     int totalScore= 0; 
     var objScore = new EngineService(); 

     for (int i = 0; i < frames.Length; i++) 
     { 
      Boolean wasSpare = false; 

      if (i > 0 && objScore.IsSpare(frames[i-1])) 
      { 
       wasSpare = true; 
      } 
      totalScore += objScore.CalculateScore(frames[i], wasSpare); 
     } 

     return Json("{\"score\":"+ totalScore + "}"); 
    } 

Надеясь, чтобы проверить с помощью следующей записи: Но не знаю, как !!!

[{""1stRoll"":2,""2ndRoll"":2 ,""3rdRoll"":0}, 
    {""1stRoll"":4,""2ndRoll"":8 ,""3rdRoll"":0}, 
    {""1stRoll"":6,""2ndRoll"":2 ,""3rdRoll"":0}]; 

Любая помощь/идея/предложение будет оценено для следующего испытания блока. Как SubmitBowlingScore() принял бы Frame [] данные как параметр?

[TestMethod] 
    public void SubmitBowlingScore() 
    { 
     //Arrange 
     HomeController controller = new HomeController(); 
     //Act 
     JsonResult result = controller.SubmitBowlingScore(**What goes here???**) as JsonResult; 

     //Assert 
     Assert.IsNotNull(JsonResult, "No JsonResult returned from action method."); 
     Assert.AreEqual(@"{[{""1stRoll"":""2"",""2ndRoll"":2 ,""3rdRoll"":0},{""1stRoll"":""2"",""2ndRoll"":8 ,""3rdRoll"":0},{""1stRoll"":""6"",""2ndRoll"":2 ,""3rdRoll"":0}],""Count"":3,""Success"":true}", 
       result.Data.ToString()); 
    } 
+1

Для начала, не делать конкатенации строк, чтобы вернуть структуру JSon. Вы можете вернуть анонимный объект, например 'return Json (new {score = 250});' – Shyju

+0

Хорошо, я понимаю, что для самого метода Action в контроллере. Но для метода единичных испытаний? – shaz

+1

Еще одна вещь, которую я мог видеть, - это прямое создание EngineService(). Вы знаете об инъекции зависимостей? EngineService - это зависимость от контроллера, поэтому его нужно скорее вводить вместо использования нового ключевого слова и создания объекта самостоятельно. Таким образом, у вас есть свободная муфта, и эта свободная муфта обеспечивает не только модульное тестирование, но и делает систему расширяемой. Надеюсь, это поможет. – VivekDev

ответ

0

Вы смешиваете свою бизнес-логику с логикой представления. Вы должны переместить весь тело вашего метода контроллера на объект, который вычисляет оценку на основе фреймов. После того, как вы получили, что нет ничего, чтобы проверить в контроллере (если вы не доверяете фреймворке ..)

Моего исполнение вашей рамки модели:

public class Frame 
{ 
    public int FirstRoll { get; set; } 
    public int SecondRoll { get; set; } 
    public int ThirdRoll { get; set; } 
} 

Вот бизнес-логику как расширение. Возможно, вы захотите разбить его на свой класс или, возможно, сделать его членом вашего класса EngineService.

public static class FrameExtensions 
{ 
    public static int SumFrameScores(this Frame[] frames) 
    { 
     //break out early if no frames have been recorded 
     if (frames.Length == 0) return 0; 

     int totalScore = 0; 
     var objScore = new EngineService(); 

     for (int i = 0; i < frames.Length; i++) 
     { 
      bool wasSpare = objScore.IsSpare(frames[i - 1]); 
      totalScore += objScore.CalculateScore(frames[i], wasSpare); 
     } 

     return totalScore; 
    } 
} 

Когда вы проверяете, вы можете проверить непосредственно против ваших C# классов/типов, поэтому вам не нужно беспокоиться о JSON/презентации перевода данных слоя.

[TestMethod] 
public void SubmitBowlingScore() 
{ 
    //Arrange 
    var frames = new Frame[] 
    { 
      new Frame {FirstRoll = 2, SecondRoll = 2, ThirdRoll = 0}, 
      new Frame {FirstRoll = 2, SecondRoll = 6, ThirdRoll = 0}, 
      new Frame {FirstRoll = 0, SecondRoll = 9, ThirdRoll = 0} 
    }; 
    //Act 
    var score = frames.SumFrameScores(); 

    //Assert 
    Assert.AreEqual(21, score); 
} 

Наконец, контроллер сводится к следующему:

[HttpPost] 
public JsonResult SubmitBowlingScore(Frame[] frames) 
{ 
    var finalScore = frames.SumFrameScores(); 
    return Json(new { score = finalScore }); 
} 
Смежные вопросы