2013-01-08 56 views
2

我正在對我的實體執行一些單元測試,並且我有一點嘲諷屬性的心理塊。看看下面的實體:在實體中嘲弄ICollection屬性

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; } 
} 

我有一個名爲AddStudentTeacher的方法,它首先檢查是否老師有太多的學生打電話給Bob分配。如果是這樣,那麼我會提出一個自定義異常,說太多的鮑勃。該方法是這樣的:

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); 
} 

我想單元測試這種使用起訂量嘲笑 - 特別是我想嘲笑的Teacher.Students.Count方法,我可以通過它的任何表達式,它會返回一個數字表明目前有10個Bob分配給該老師。我將其設置是這樣的:

[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其中推斷的ICollection.Count方法不是虛擬的,因此不能被嘲笑。我如何模擬這個特定的功能?

任何幫助總是感激!

回答

5

您無法模擬您正在使用的方法Count,因爲它是一種擴展方法。這不是在ICollection<T>上定義的方法。
最簡單的解決方法是簡單地用10個鮑勃名單分配給Students屬性:

teacher.Students = Enumerable.Repeat(new Student { Name = "Bob" }, 10) 
          .ToList(); 
+0

作爲一個側面說明,痣或假貨框架允許嘲笑擴展方法。 – daryal

+0

@DanielHilgarth當然!我知道這是類似的東西,按照預期工作,現在感謝。 –

0

沒有必要嘲笑集合時,你可以簡單地檢查有無異常被拋出使用真正的集合,而不是一個模擬。當你正在使用MSTest的,而不是NUnit的,你不能簡單地添加的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); 
+0

不應該是'Assert.IsTrue(hasTooManyBobs);'? – tallseth

+0

MSTest支持[ExpectedException屬性](http://msdn.microsoft.com/zh-cn/library/microsoft.visualstudio.testtools.unittesting.expectedexceptionattribute.aspx)。不需要try-catch塊。 –