Hiện chúng tôi đang gặp phải một số vấn đề trong khi kiểm tra Đơn vị. Lớp của chúng ta đa luồng một số lời gọi hàm trên các đối tượng Mocked bằng cách sử dụng Rhino Mocks. Dưới đây là một ví dụ giảm xuống mức tối thiểu:Mã đa luồng làm cho Rhino Mocks gây ra một Deadlock
public class Bar
{
private readonly List<IFoo> _fooList;
public Bar(List<IFoo> fooList)
{
_fooList = fooList;
}
public void Start()
{
var allTasks = new List<Task>();
foreach (var foo in _fooList)
allTasks.Add(Task.Factory.StartNew(() => foo.DoSomething()));
Task.WaitAll(allTasks.ToArray());
}
}
Giao diện IFoo được định nghĩa là:
public interface IFoo
{
void DoSomething();
event EventHandler myEvent;
}
Để tái tạo các bế tắc, unittest của chúng tôi thực hiện như sau: 1. tạo ra một số IFoo Mocks 2. Tăng myEvent khi DoSomething() được gọi.
[TestMethod]
public void Foo_RaiseBar()
{
var fooList = GenerateFooList(50);
var target = new Bar(fooList);
target.Start();
}
private List<IFoo> GenerateFooList(int max)
{
var mocks = new MockRepository();
var fooList = new List<IFoo>();
for (int i = 0; i < max; i++)
fooList.Add(GenerateFoo(mocks));
mocks.ReplayAll();
return fooList;
}
private IFoo GenerateFoo(MockRepository mocks)
{
var foo = mocks.StrictMock<IFoo>();
foo.myEvent += null;
var eventRaiser = LastCall.On(foo).IgnoreArguments().GetEventRaiser();
foo.DoSomething();
LastCall.On(foo).WhenCalled(i => eventRaiser.Raise(foo, EventArgs.Empty));
return foo;
}
Càng nhiều Foo được tạo, càng thường xảy ra bế tắc. Nếu kiểm tra sẽ không chặn, hãy chạy nó nhiều lần, và nó sẽ. Dừng gỡ lỗi chương trình testrun, rằng tất cả các nhiệm vụ vẫn còn trong TaskStatus.Running và các sợi nhân hiện nay là vi phạm tại
[Trong một giấc ngủ, chờ đợi, hoặc tham gia]
Rhino.Mocks.dll! Rhino. Mocks.Impl.RhinoInterceptor.Intercept (Castle.Core.Interceptor.IInvocation gọi) + 0x3d byte
điều lạ mà confuses chúng tôi hầu hết là một thực tế, rằng chữ ký của Intercept (...) Phương pháp được định nghĩa là Synchronized - nhưng một số Threads được đặt ở đây. Tôi đã đọc một số thông tin về Rhino Mocks và Multithreaded, nhưng không tìm thấy cảnh báo (dự kiến thiết lập các bản ghi) hoặc các hạn chế.
[MethodImpl(MethodImplOptions.Synchronized)]
public void Intercept(IInvocation invocation)
Chúng tôi đang làm điều gì đó hoàn toàn sai khi thiết lập Mockobject hoặc sử dụng chúng trong môi trường đa luồng? Bất kỳ trợ giúp hoặc gợi ý được hoan nghênh!
Tôi thấy điều này [http://blog.smithfamily.dk/post/2011/03/26/Thread-safe-version-of-Rhino-Mocks.aspx](http://blog.smithfamily.dk/ post/2011/03/26/Thread-safe-version-of-Rhino-Mocks.aspx) trên các chuyến đi google của tôi. Đáng buồn thay, phiên bản được lưu trữ ở đó dường như có một lỗi trong đó, vì vậy tôi không thể nhìn thấy nếu nó sửa vấn đề. – jasper