2012-07-09 65 views
1

我想測試從多個線程調用某個方法時,沒有併發問題。我模擬該方法被同時調用3次,並在緩存中插入2000個客戶,以確保沒有併發問題。此測試對測試併發問題有意義嗎?

public void Should_Insert_2000_Customers_Using_Concurrency() 
{ 
    var fakeCustomers = InitCustomersFromDb(); 
    Action insertCustomersFrom_0_to_1000 = new Action(() => 
    { 
     Parallel.For(0, 1000, x => 
     { 
      CustomerCache.Instance.SetCustomer(x.ToString(), fakeCustomers[0]); 
     }); 

    }); 
    Action insertCustomersFrom_1000_to_2000 = new Action(() => 
    { 
     Parallel.For(1000, 2000, x => 
     { 
      CustomerCache.Instance.SetCustomer(x.ToString(), fakeCustomers[0]); 
     }); 
    }); 
    Action insertCustomersFrom_0_to_2000 = new Action(() => 
    { 
     Parallel.For(0, 2000, x => 
     { 
      CustomerCache.Instance.SetCustomer(x.ToString(), fakeCustomers[0]); 
     }); 
    }); 
    List<Task> tasks = new List<Task>(); 
    tasks.Add(Task.Factory.StartNew(insertCustomersFrom_0_to_1000)); 
    tasks.Add(Task.Factory.StartNew(insertCustomersFrom_1000_to_2000)); 
    tasks.Add(Task.Factory.StartNew(insertCustomersFrom_0_to_2000)); 

    Task.WaitAll(tasks.ToArray()); 
    var customers = CustomerCache.Instance.GetCustomers(); 
    Assert.That(customers.Count == 2000); 
} 

將在運行對我CustomerCache多個同時Parallel.For迭代是在表現出任何的併發問題是否有效?

+2

那麼你的問題是什麼?你是否要求進行代碼審查? – slugster 2012-07-09 09:23:03

+0

我想知道這些測試是否適合測試多線程。或者,如果它沒用... – Florian 2012-07-09 09:30:24

+0

Parallel.For是異步的,所以你使用更多的線程,取決於你有多少個CPU /核心。 – Maarten 2012-07-09 09:31:39

回答

1

測試需要測試特定場景。併發測試需要創建併發問題,而不是希望發生。測試應該需要一次運行。如果在你的代碼中這很難記住,那裏有比可測試代碼更多的功能代碼。但是......爲了降低風險......你想讓你的代碼可測試。

因此,通過「併發」來確定你的意思並使之成爲現實。要自信。調用一個方法並模擬它調用的內容。當它調用告訴你它在關鍵部分的東西時,則使用模擬框架來調用另一個調用。

你現在可能想知道「但這意味着多個線程」。線程是一個概念,注入用於創建線程的對象和任何處理衝突的對象。

你必須看着一兩條線,思考....「兩個可以做到這一點」。測試警衛。

3

IMO,這種測試不會透露太多。當然,對於這種特殊情況,很明顯,結果在最後是正確的,但是在一般情況下,您要同時在一個集合中插入項目,測試實際添加的項目的數量會產生誤導,因爲要獲取您期望並不排除在某個地方出現數據競爭的可能性,以及你「幸運」的可能性。