2012-01-18 3 views
3

내가(화이트 박스 테스트) 여기

private static void selectTop20Tags(Dictionary<string, int> list) 
    { 

     //Outputs the top 20 most common hashtags in descending order 
     foreach (KeyValuePair<string, int> pair in list.OrderByDescending(key => key.Value).Take(20)) 
     { 
      Console.WriteLine("{0}, {1}", pair.Key, pair.Value); 
     } 

    } 

나는 이것을 테스트 할 방법을 모르는를 테스트 할 방법이다, 나는 여러 가지를 하루 종일을 연구하고 시도했습니다 그러나 그것을 작동시킬 수는 없습니다.

난 그냥 예를 볼 필요가 있고 내가 아는 것이라고 생각 같은

#if TEST 
      if ((length of list don't know how you would do it) <= 20) 
      { 
       StreamWriter log2; 
       // appends file 
       log2 = File.AppendText("logOfTests.txt"); 
       // Writes to the file 
       log2.WriteLine("PASS"); 
       log2.WriteLine(); 

       // Closes the stream 
       log2.Close(); 
      } 
#endif 

일부 코드를 포함 생각했다.

+5

NRE를 잡지 않습니다. 너는 그것을 막는다. –

+3

당신의 메소드는'Console'을 사용하기 때문에 본질적으로 테스트하기가 어렵습니다. 대신에'Console.Out'을 사용하는 과부하가있는'TextWriter'를 전달할 수 있습니까? –

+0

@Anthony Pegram O.k 역시 예외 처리가 확실하지 않습니다. – Elliot678

답변

4

단위 테스트에 대해 배우는 것이 좋습니다. MSDN에서 this 문서를 읽고 Google에서 단위 테스트 작성 방법을 검색하십시오. 코드의 개별 단위를 테스트하는 가장 좋은 방법이므로 상황에 이상적이어야합니다.

MessageBox, 기타 UI 요소 및 Console에 대한 호출과 같은 UI 관련 코드를 구분하는 것이 좋습니다. 테스트하려는 코드에서 이렇게하면 논리 및 코드 실행을 훨씬 쉽게 테스트 할 수 있습니다.

2

사무엘 슬레 이드 (Samuel Slade)의 답변 - 단위 테스트와 이해 관계 주입 및 제어 반전의 원칙에 동의하는 것은 그러한 시스템을 테스트하는 데 분명 도움이 될 것입니다.

나는 최적의 것은 아니지만 코드에 대한 테스트 작성 방법 (의존성 주입과 함께)과 코드가 작동하는지 테스트하는 방법을 보여줍니다.

나는 몇 가지 가정을해야했지만 잘하면 그것이 의미가 있습니다. 추가 질문이있는 경우 알려 주시면 설명해 드리겠습니다.

이 정보가 도움이되기를 바랍니다. 행운을 빕니다!

CodeUnderTest

namespace CodeUnderTest 
{ 
    public interface IMessageBox 
    { 
     DialogResult Show(string message, string title, MessageBoxButtons buttons, MessageBoxIcon icon); 
    } 

    public class MessageBoxService : IMessageBox 
    { 
     public DialogResult Show(string message, string title, MessageBoxButtons buttons, MessageBoxIcon icon) 
     { 
      return MessageBox.Show(message, title, buttons, icon); 
     } 
    } 

    public class MessageBoxFake : IMessageBox 
    { 
     public DialogResult Show(string message, string title, MessageBoxButtons buttons, MessageBoxIcon icon) 
     { 
      return DialogResult.OK; 
     } 
    } 


    public class Repository 
    { 
     private readonly TextWriter _console; 
     private readonly IMessageBox _messageBox; 

     public Repository(TextWriter console, IMessageBox msgBox) 
     { 
      _console = console; 
      _messageBox = msgBox; 
     } 

     public void WriteTop20Tags(Dictionary<string, int> list) 
     { 
      selectTop20Tags(list, _console, _messageBox); 
     } 

     private static void selectTop20Tags(Dictionary<string, int> list, TextWriter _console, IMessageBox _messageBox) 
     { 
      try 
      { 
       //Outputs the top 20 most common hashtags in descending order 
       foreach (KeyValuePair<string, int> pair in list.OrderByDescending(key => key.Value).Take(20)) 
       { 
        _console.WriteLine("{0}, {1}", pair.Key, pair.Value); 
       } 
      } 
      catch (NullReferenceException e) 
      { 
       _messageBox.Show(e.Message, "Error detected", MessageBoxButtons.OK, MessageBoxIcon.Error); 
      } 
     } 
    } 
} 

단위 테스트

class When_I_Pass_A_Valid_Dictionary_I_Should_See_My_List_Output_To_My_Writer 
{ 
    static void Main(string[] args) 
    { 
     //Arrange 
     //dummy data 
     var list = new Dictionary<string, int>() 
     { 
      {"a", 100}, 
      {"b", 200}, 
      {"c", 300}, 
      {"d", 400} 
     }; 

     using (StringWriter sw = new StringWriter()) 
     { 
      //Act 
      //var repo = new CodeUnderTest.Repository(Console.Out, new CodeUnderTest.MessageBoxFake()); 
      var repo = new CodeUnderTest.Repository(sw, new CodeUnderTest.MessageBoxFake()); 
      repo.WriteTop20Tags(list); 

      //Assert 
      //expect my writer has contents 
      if (sw.ToString().Length > 0) 
      { 
       Console.WriteLine("success"); 
      } 
      else 
      { 
       Console.WriteLine("failed -- string writer was empty!"); 
      } 
     } 

     Console.ReadLine(); 
    } 
} 
1

당신은 콘솔 클래스의 동작을 시뮬레이션하기 위해 마이크로 소프트 두더지를 사용할 수 있습니다. 아래 예를보십시오.

namespace TestesGerais 
{ 
    public class MyClass 
    { 
     public static void selectTop20Tags(Dictionary<string, int> list) 
     { 
      //Outputs the top 20 most common hashtags in descending order 
      foreach (KeyValuePair<string, int> pair in list.OrderByDescending(key => key.Value).Take(20)) 
      { 
       Console.WriteLine("{0}, {1}", pair.Key, pair.Value); 
      } 
     } 
    } 

    [TestClass] 
    public class UnitTest6 
    { 
     [TestMethod] 
     [HostType("Moles")] 
     public void TestMethod1() 
     { 
      // Arrange 
      var actual = new List<string>(); 
      MConsole.WriteLineStringObjectObject = (s, o1, o2) => actual.Add(string.Format(s, o1, o2)); 
      var dic = new Dictionary<string, int>(); 
      for (int i = 1; i < 30; i++) 
       dic.Add(string.Format("String{0}", i), i); 
      var expected = new List<string>(); 
      expected.AddRange(new[] { "String29, 29", "String28, 28", "String27, 27", "String26, 26", "String25, 25", "String24, 24", "String23, 23", "String22, 22", "String21, 21", "String20, 20", "String19, 19", "String18, 18", "String17, 17", "String16, 16", "String15, 15", "String14, 14", "String13, 13", "String12, 12", "String11, 11", "String10, 10" }); 
      // Act 
      MyClass.selectTop20Tags(dic); 
      // Assert 
      CollectionAssert.AreEqual(expected, actual); 
     } 
    } 
} 

여기서 콘솔에 대한 호출을 가로 채서 결과를 평가할 수 있습니다. Moles 프레임 워크에 대한 자세한 내용은 http://research.microsoft.com/en-us/projects/moles/을 참조하십시오.

그러나 저는 다른 사람들과 동의합니다. 단원 테스트에 대한 자세한 내용을 읽고 의존성을 격리해야합니다 ... 우리는 Moles로 코드를 테스트 할 수 있지만 IMHO는 최선의 방법은 아닙니다.

+0

+1 - 나는 Moles에 대해 들어 봤지만 결코 사용하지 않았습니다. 흥미로운 것 같지만, 나는 당신에게 동의한다 - 그것은 최선의 방법이 아닐 수도있다. 그러나 이것은 까다로운 레거시 코드에 유용합니다. –

관련 문제