2015-06-21 61 views
2

當我正常運行測試代碼時,NUnit通知我測試失敗。 result.Contacts的值是3,而不是預期的1.當測試代碼在測試代碼中的assert語句中帶有斷點時運行時,測試不會失敗。我懷疑這是與多線程相關的問題。測試異步方法會產生奇怪的結果

這是我的測試代碼

[Test] 
public async Task Method_Scenario_IncreasesCount() 
{ 
    // Arrange 
    const int employeeId = 1; 
    const string managerId = "asdf"; 

    // Act 
    var result = await _uut.Contact(managerId , employeeId); 

    // Assert 
    Assert.That(result.Contacts, Is.EqualTo(1)); 
} 

這是測試下的代碼

public async Task<MyObject> Contact(string managerId, int employeeId) 
{ 
    var today = DateTime.UtcNow.Date; 

    var myStoredObject = _myObjectRepository.GetAll().Include(p => p.Employee).First(x => x.Employee.Id == employeeId); 

    myStoredObject.Contacts += 1; 
    myStoredObject.LastContact = today; 

    var dates = new List<DateTime> 
    { 
     myStoredObject.FirstDate, 
     myStoredObject.SecondDate, 
     myStoredObject.ThirdDate 
    }; 

    if (!dates.Contains(today)) 
    { 
     await _logging.Log(myStoredObject, Log.Extra); 

     await _myObjectRepository.UpdateAsync(myStoredObject); 
    } 

    return myStoredObject; 
} 

_myObjectRepository_logging對象使用Moq嘲笑;而且myStoredObject是由我預定義的,所以我知道聯繫人的值是0開始的。

爲什麼只有在斷言語句中使用斷點時才通過測試?我該如何解決這個問題?


編輯

我用Moq要做到這一點也嘗試:

_mock.Verify(r => r.UpdateAsync(It.Is<MyObject>(m => m.Contacts == 1))); 

但是,這也將失敗,與MockException說:

預期在模擬上至少調用一次,但從未執行過。

然而,如果我通過程序步驟,我可以看到,這個方法稱爲帶有MyObject具有Contacts = 1

回答

2

很難說沒有看到您的[SetUp]代碼可能會導致您的問題。我注意到你的模擬和被測試單元是成員變量 - 也許在與另一個測試共享狀態時出現問題。我能夠編寫相同的測試,並且一致地通過

[Test] 
public async Task Method_Scenario_IncreasesCount() 
{ 
    // Arrange 
    const int employeeId = 55378008; 
    var existingEntity = new MyObject {Employee = new Employee {Id = employeeId}}; 
    var repo = Mock.Of<IMyObjectRepo>(r => r.GetAll() == new[] {existingEntity}.AsQueryable()); 
    var uut = new MyUut(repo, Mock.Of<ILog>()); 

    // Act 
    var entity = await uut.Contact(string.Empty, employeeId); 

    // Assert 
    Assert.That(entity.Contacts, Is.EqualTo(1)); 
    Mock.Get(repo).Verify(r => r.UpdateAsync(entity)); 
} 
+0

這就解決了這個問題。非常好發現!該對象在我的測試類的構造函數中初始化。我把它移到了setup方法中,現在一切都按預期工作。但是我仍然不明白爲什麼當我用調試器遍歷代碼時它會通過。 –

相關問題