2017-11-24 7 views
0

私は現在、以下のコードを単体テストしようとしており、実際にどこに行くべきか分からない。ちょっと読んだら、私は偽装/偽装を使用して単体テストに渡すことができる擬似jsonディレクトリを初期化する必要があると思うが、黙っていることは本当に複雑に思えます。これに関するどんな助けも素晴らしいだろう。事前に おかげで、 KユニットテストにC#でjsonを模倣する

 public static string ShowLocation = Directory.GetCurrentDirectory() + @"\Database\Shows.txt"; 
    public static string GoldMemberLocation = Directory.GetCurrentDirectory() + @"\Database\GoldMembers.txt"; 

    /// <summary> 
    /// Deletes a specific show from the database. 
    /// </summary> 
    /// <param name="show"></param> 
    public static void DeleteShow (Show show) 
    { 
     if (Directory.Exists(ShowLocation)) 
     { 
      string json = File.ReadAllText(ShowLocation); 

      List<Show> data = JsonConvert.DeserializeObject<List<Show>>(json); 
      data.Remove(show); 

      json = JsonConvert.SerializeObject(data.ToArray()); 

      File.WriteAllText(ShowLocation, json); 
     } 
     else 
     { 
      File.WriteAllText(ShowLocation, String.Empty); 
      SaveShow(show); 
     } 
    } 

    /// <summary> 
    /// Saves a new Show. 
    /// </summary> 
    /// <param name="show"></param> 
    public static void SaveShow(Show show) 
    { 
     if (File.Exists(ShowLocation)) 
     { 
      string json = File.ReadAllText(ShowLocation); 

      var data = new List<Show>(); 

      FileInfo f = new FileInfo(ShowLocation); 
      if (f.Length > 0) 
      { 
       data = JsonConvert.DeserializeObject<List<Show>>(json); 
      } 

      data.Add(show); 

      json = JsonConvert.SerializeObject(data.ToArray()); 

      File.WriteAllText(ShowLocation, json); 
     } 
     else 
     { 
      var data = new List<Show>(); 

      data.Add(show); 

      var json = JsonConvert.SerializeObject(data.ToArray()); 

      File.WriteAllText(ShowLocation, json); 
     } 
    } 

    /// <summary> 
    /// Loads all the shows. 
    /// </summary> 
    /// <returns></returns> 
    public static List<Show> LoadShows() 
    { 
     if (File.Exists(ShowLocation)) 
     { 
      string json = File.ReadAllText(ShowLocation); 

      List<Show> data = JsonConvert.DeserializeObject<List<Show>>(json); 

      return data; 
     } 
     else 
     { 
      File.WriteAllText(ShowLocation, String.Empty); 
      return new List<Show>(); 
     } 

    } 

    /// <summary> 
    /// Deletes a specific gold member. 
    /// </summary> 
    /// <param name="goldMember"></param> 
    public static void DeleteGoldMember(GoldMember goldMember) 
    { 
     if (File.Exists(GoldMemberLocation)) 
     { 
      string json = File.ReadAllText(GoldMemberLocation); 

      List<GoldMember> data = JsonConvert.DeserializeObject<List<GoldMember>>(json); 
      data.Remove(goldMember); 

      json = JsonConvert.SerializeObject(data.ToArray()); 

      File.WriteAllText(GoldMemberLocation, json); 
     } 
     else 
     { 
      File.WriteAllText(GoldMemberLocation, String.Empty); 
     } 
    } 

    /// <summary> 
    /// Saves a new Gold member 
    /// </summary> 
    /// <param name="goldMember"></param> 
    public static void SaveGoldMembers (GoldMember goldMember) 
    { 

     if (File.Exists(GoldMemberLocation)) 
     { 
      string json = File.ReadAllText(GoldMemberLocation); 
      var data = new List<GoldMember>(); 

      FileInfo f = new FileInfo(GoldMemberLocation); 
      if (f.Length > 0) 
      { 
       data = JsonConvert.DeserializeObject<List<GoldMember>>(json); 
      } 

      data.Add(goldMember); 

      json = JsonConvert.SerializeObject(data.ToArray()); 

      File.WriteAllText(GoldMemberLocation, json); 
     } 
     else 
     { 
      var data = new List<GoldMember>(); 
      data.Add(goldMember); 

      var json = JsonConvert.SerializeObject(data.ToArray()); 

      File.WriteAllText(GoldMemberLocation, json); 
     } 

    } 
+3

コードは、テストすることは不可能ではありませんが、テストを実行するための物理ファイルが必要です。抽象化の背後にあるIO呼び出しをカプセル化して、コードを分離してテストするのがより簡単になるように、分離し分離します。 – Nkosi

+0

@Nkosiこれで私が読んだ例やリンクをどこかに与えることは可能でしょうか? –

+1

これは、ユニットテストの可能性が限られているデータレイヤーです。私は、おそらく単体テストとは対照的にこのコードを統合テストでカバーするでしょう。しかし、リファクタリングする必要がありますインターフェイスと静的ではないので、それはあなたのユニットロジックの大部分を行うビジネスロジック層に注入することができますテストします。スチュアートの答えは、あなたが実際に行うことができるのはあなたのメソッドが呼び出されたと主張されているので、使用が制限されていることがわかります。 – Crowcoder

答えて

0

OK]をクリックして、物事は、それがファイルIOでテストあなたを停止しました。したがって、これらのメソッドをインターフェースに引き込み、そのインターフェースをモックする必要があります。

次に、これらの模擬メソッドを返すように設定します。

// A concrete implementation you will use at runtime. 
public class FileHelper : IFileHelper 
{ 
    bool DirectoryExists(string location) => Directory.Exists(location); 
    string ReadAlltext(string location) => File.ReadAllText(location); 
    void WriteAlLText(string location, string text) => File.WriteAlLText(location, text); 
} 

public interface IFileHelper 
{ 
    bool DirectoryExists(string location); 
    string ReadAlltext(string location); 
    WriteAllText(string location, string text); 
} 
[TestMethod] 
public void TestDeleteShow() 
{ 
    // Create a mock of your FileHelper and setup 
    // the methods and what you want them to return. 
    Mock<IFileHelper> fileHelper = new Mock<IFileHelper>(); 
    fileHelper.Setup(x=>x.DirectoryExists).Returns(true); 
    fileHelper.Setup(x=>x.ReadAllText).Returns(/* put some text in here */); 
    string testLocation = "foo"; 
    Foo.DeleteShow(testLocation); 

    // Verify the methods on your mock were called, as expected. 
    fileHelper.Verify(x=>x.WriteAlLText(It.IsAny<string>(), string.Empty)); 
} 

特定のパラメータで特定のメソッドが呼び出されたことを確認できます。私の例はMoqを使用しています。

たとえば、DirectoryExistsがfalseを返すテストを設定し、File.WriteAllTextが空の文字列と正しい場所で呼び出されたことを確認できます。

上記のコメントは、これはロジックをテストしないと言っています...存在しないディレクトリを渡すと、ファイルが作成されたと主張できますその場所でそれは空です。同様に存在する場合は、メソッドを呼び出しても正しい内容を渡すことができます。

これは、そのメソッドの唯一のロジックです...もちろん、File.WriteAllLinesが動作することをテストできますが、それは.netライブラリメソッドです。あなたがそれを間違ってやっている.netフレームワークをテストしているなら、同様に、JSonConvertをテストする必要はありません....私はあなたに例を挙げました。ロジックをテストして、ディレクトリに存在するディレクトリは、その方法の唯一のロジックです。

関連する問題