2013-06-26 71 views
-3

我的測試案例總是失敗,請告訴我,我錯了,代碼如下C#單元測試嘲諷使用Moq.dll

public class EmployeeService 
{ 
    private readonly IRepository _repository; 

    public EmployeeService(IRepository repository) 
    { 
     _repository = repository; 
    } 

    public bool SaveEmployeeData(Employee employee,bool isSaveNeeded) 
    { 
     bool result = false; 
     try 
     { 
      if (isSaveNeeded) 
      { 
       result= _repository.Save(employee); 
      } 
     } 
     catch (Exception ex) 
     { 
      throw new Exception(); 
     } 
     return result; 
    } 
} 

和我的測試用例是

[TestMethod()] 
public void SaveEmployeeDataTest() 
{ 
    var a = new Mock<IRepository>(); 
    a.Setup(s => s.Save(new Employee())).Returns(true).Verifiable(); 
    var result = new EmployeeService(a.Object).SaveEmployeeData(new Employee(), true); 
    Assert.IsTrue(result); 
} 

它總是失敗。

+2

*它失敗了嗎? (爲什麼你有一個catch塊,它只​​丟失信息,爲什麼你不想拋出原來的異常呢?) –

回答

3

new Employee()每次都會創建一個新員工實例,一次用於設置Save,另一個用於實際SaveEmployeeData。因此,所提供的員工永遠不符合設置的要求。

要麼使用一個包羅萬象的做法一樣lazyberezovsky的答案,或執行以下操作:

[TestMethod()] 
public void SaveEmployeeDataTest() 
{ 
    var a = new Mock<IRepository>(); 
    var employee = new Employee(); 
    a.Setup(s => s.Save(employee)).Returns(true).Verifiable(); 
    var result = new EmployeeService(a.Object).SaveEmployeeData(employee, true); 
    Assert.IsTrue(result); 
} 

因爲同樣Employee實例在安裝使用中的實際調用,設置匹配和正確的結果返回。

4

使用It.IsAny<Employee>設置保存方法參數

a.Setup(s => s.Save(It.IsAny<Employee>())).Returns(true).Verifiable(); 

之所以測試不工作是因爲你有兩個不同的員工實例 - 一個用於模擬設置,以及一個被傳遞到SaveEmployeeData方法調用。默認情況下,這些實例將通過引用進行比較。 Moq等待Save方法調用僱員實例,其中引用13(例如)。但是你傳遞了另一個僱員的參考文獻42.因此,從不調用安裝程序。

你有兩個選擇

  • 覆蓋EqualsEmployee類的GetHashCode方法。因此,Moq將比較員工而不是通過參考,而是通過業務數據。

    [TestMethod()] 
    public void SaveEmployeeDataTest() 
    { 
        var a = new Mock<IRepository>(); 
        var sameEmployee = new Employee(); 
        a.Setup(s => s.Save(sameEmployee)).Returns(true).Verifiable(); 
    
        var service = new EmployeeService(a.Object); 
        var result = service.SaveEmployeeData(sameEmployee, true); 
        Assert.IsTrue(result); 
    } 
    

    重寫平等:

    public class Employee 
    { 
        public override bool Equals(object obj) 
        { 
         Employee other = obj as Employee; 
         if (other == null) 
          return false; 
    
         return this.Id == other.Id; // for example 
        } 
    } 
    

  • 使用完全相同既爲模擬設置和SaveEmployeeData方法調用(優選方式)相同的僱員實例的

用法僱員的實例在這種情況下,您可以保持原樣。

+0

但是這並不能測試正確的僱員實例是否用於方法調用。這是一半的測試。如果在你的代碼中你沒有使用傳入方法的employee對象,而是創建一個新的testcase將永遠不會檢測到它。 – JustCode

+0

@JustCode抱歉,沒有得到你 –

+1

對不起,我忽略了你答案的底部。它的完美現在:-) – JustCode

1

試試這個 -

[TestMethod()] 
public void SaveEmployeeDataTest() 
{ 
    var a = new Mock<IRepository>(); 
var employee = new Employee(); 
    a.Setup(s => s.Save(employee)).Returns(true).Verifiable(); 
    var result = new EmployeeService(a.Object).SaveEmployeeData(employee, true); 
    Assert.IsTrue(result); 
} 

您需要使用設置一個員工實例和方法調用。這將確保驗證您正在使用在方法中傳遞的同一個員工實例,而不是在方法中創建或從其他方法返回的東西。