3

悪いタイトルの言い訳:誰かがそれをよりよく説明できる場合はどうかしてください。弱点リストのメモリ管理機能を(ユニット)テストする方法は?

私はWeakList<T>クラスを持っていますが、これは基本的にList<WeakReference<T>>です(リストから派生した文字通りではありませんが、ユーザーにとって完全に透過的でなければなりません)。 Listは、実際にここに理にかなっている場合、私はまだ考えています

public class WeakList<T> : IReadOnlyList<T>, IWeakList<T>, IWeakCollection<T>, IReadOnlyCollection<T>, 
    ICollection<T>, IEnumerable<T>, IEnumerable where T : class 
{ 
    private readonly List<WeakReference<T>> _myList; 
    public void Add(T item) { 
     _myList.Add(new WeakReference<T>(item)); 
    } 
    IEnumerator<T> IEnumerable<T>.GetEnumerator() { 
     foreach (var reference in _myList) { 
      T elem; 
      if (reference.TryGetTarget(out elem)) { 
       yield return elem; 
      } 
     } 
    } 
} 

、weaklist:

は今、基本的な考え方は、すなわち WeakList<T>ソースの一部である、「参照変数がなくなった場合の項目は無視されている」ということです[n]は、n番目の要素を反復することと常に同じではありません。 - 注文はあるが、インデックスベースのアクセスはないコレクション名があるか?

ただし、この点以外にも: このクラスには、「削除した既存の参照を削除する」機能が含まれています。

public void Purge() { 
     for (int i = _myList.Count - 1; i >= 0; i--) { 
      T elem; 
      if (!_myList[i].TryGetTarget(out elem)) { 
       _myList.RemoveAt(i); 
      } 
     } 
    } 

私の質問は、ユニットテスト(Nunit用)で上記の方法をテストするにはどうすればいいですか?どうすればセットアップリストは、その後、いくつかの要素が削除されていることを確認することができ、その後のようなもの、パージを呼び出して、それをテストします。コメントは、私がこだわっているどのポイントで説明し

[TestFixture] 
public class WeakListTests 
{ 
    [Test] 
    public static void PurgeTest() { 
     var myList = new WeakList<string>; 
     string s1 = "hello world 1"; 
     string s2 = "hello world 2"; 
     string s3 = "hello world 3"; 
     myList.Add(s1); 
     myList.Add(s2); 
     myList.Add(s3); 
     // "clear", force s1 & s2 away. (yet keep a reference so I can test it gets removed) 
     myList.Purge(); 
     Assert.That(myList, Does.Not.Contain(s1)); 
     Assert.That(myList, Does.Not.Contain(s2)); 
     Assert.That(myList, Does.Contain(s3)); 

    } 
} 

答えて

1

あなたは(コメントを参照)、このようにそれを行うことができます。

[TestFixture] 
public class WeakListTests 
{ 
    [Test] 
    public static void PurgeTest() 
    { 
     var myList = new WeakList<string>(); 
     // construct strings like this to prevent interning 
     string s1 = new string(new[] { 'h', 'e', 'l', 'l', 'o' }); 
     string s2 = new string(new[] { 'h', 'e', 'l', 'l', 'o', '2' }); 
     // this string can be interned, we don't want it to be collected anyway 
     string s3 = "hello world 3";    
     myList.Add(s1); 
     myList.Add(s2); 
     myList.Add(s3); 
     // set to null for that to work even in application built with "Debug" 
     // in Release it will work without setting to null 
     s1 = null; 
     s2 = null; 
     // force GC collection 
     GC.Collect(2, GCCollectionMode.Forced);    
     // now s1 and s2 are away 
     myList.Purge(); 
     // invoke your enumerator 
     var left = myList.ToArray();    
     // should contain 1 item and that item should be s3 
     Assert.That(left.Length == 1); 
     Assert.AreEqual(s3, left[0]);    
    } 
} 
+0

が、これは仕様による「動作する保証」またはそれは「単なる作業」されますか? – paul23

+0

@ paul23なぜ動作しないのかわかりません。スコープの外にある2つの変数(メソッドの下のどこでも使用されていません)があり、すぐにガベージコレクションが強制され、収集され、弱い参照はもう生きていません。しかし、何らかの理由で、何らかの不明な状況下で動作しなくても、あなたのユニットテストは失敗し、あなたは気付くでしょう。問題の場合にそのテストが黙って通れば、私はあなたの懸念を理解しますが、それは起こりません。それが合格した場合、弱い参照は生存しておらず、1は生存しています。 – Evk

+0

@ paul23とコードのどの部分が心配ですか?強制ガベージコレクション? – Evk

関連する問題