2

私は自分のエンティティでいくつかの単体テストを実行していますが、プロパティをモックする精神的なブロックが少しありました。次のエンティティを取ります。

public class Teacher
{
    public int MaxBobs { get; set; }
    public virtual ICollection<Student> Students { get; set; }
}

public class Student
{
    public string Name { get; set; }
    public virtual Teacher Teacher { get; set; }
}

教師に割り当てられた Bob という名前の生徒が多すぎるかどうかを最初にチェックするメソッドがTeacher呼び出されました。AddStudentもしそうなら、ボブが多すぎるというカスタム例外を発生させます。メソッドは次のようになります。

public void AddStudent(Student student)
{
    if (student.Name.Equals("Bob"))
    {
        if (this.Students.Count(s => s.Name.Equals("Bob")) >= this.MaxBobs)
        {
            throw new TooManyBobsException("Too many Bobs!!");
        }
    }

    this.Students.Add(student);
}

Moqモックを使用してこれを単体テストしたいと思います。具体的には、任意の式を渡すことができる.Countメソッドをモックしたいと思います。その教師に現在 10 人のボブが割り当てられていることを示す数値が返されます。Teacher.Students私は次のように設定しています:

[TestMethod]
[ExpectedException(typeof(TooManyBobsException))]
public void Can_not_add_too_many_bobs()
{
    Mock<ICollection<Student>> students = new Mock<ICollection<Student>>();
    students.Setup(s => s.Count(It.IsAny<Func<Student, bool>>()).Returns(10);

    Teacher teacher = new Teacher();
    teacher.MaxBobs = 1;

    // set the collection to the Mock - I think this is where I'm going wrong
    teacher.Students = students.Object; 

    // the next line should raise an exception because there can be only one
    // Bob, yet my mocked collection says there are 10
    teacher.AddStudent(new Student() { Name = "Bob" });
}

カスタム例外が発生することを期待していますが、実際に取得System.NotSupportedExceptionしているのは、の.CountメソッドがICollection仮想ではないためモックできないことを示しています。この特定の関数をモックするにはどうすればよいですか?

どんな助けでもいつも感謝しています!

4

2 に答える 2

6

Count拡張メソッドであるため、使用しているメソッドをモックすることはできません。で定義されたメソッドではありませんICollection<T>
最も簡単な解決策は、10 個のボブを含むリストをStudentsプロパティに割り当てることです。

teacher.Students = Enumerable.Repeat(new Student { Name = "Bob" }, 10)
                             .ToList();
于 2013-01-08T13:35:21.330 に答える
0

モックではなく実際のコレクションを使用して例外がスローされたかどうかを簡単に確認できる場合は、コレクションをモックする必要はありません。NUnit ではなく MsTest を使用しているため、単に ExpectedException 属性を追加して例外がスローされたことを確認することはできませんが、次のようなことはできます。

Teacher teacher = new Teacher();
teacher.MaxBobs = 1;

teacher.Students = new Collection<Student>(); 

var hasTooManyBobs = false;
try 
{
    teacher.AddStudent(new Student() { Name = "Bob" });
    teacher.AddStudent(new Student() { Name = "Bob" });
}
catch(TooManyBobsException)
{
    hasTooManyBobs = true;
}

Assert.IsFalse(hasTooManyBobs);
于 2013-01-08T13:46:54.450 に答える