gpt4 book ai didi

c# - Rhino Mocks AAA 语法和线程安全

转载 作者:太空宇宙 更新时间:2023-11-03 20:38:10 25 4
gpt4 key购买 nike

我有一个问题,我的测试大部分 都通过了,但偶尔会失败。我认为这可能是一个线程问题,但我已经尝试使用锁和 sleep 等来尝试找出问题所在,但没有成功。我使用的语法正确吗?离开一段时间后,我又开始使用 Rhino。

这是我的测试的净化版本。就像我说的,他们 4 次中有 3 次工作,但随后繁荣。

[TestFixture]
public class Tests
{
[Test]
public void ReprocessItems()
{
// Arrange
Presenter presenter = new Presenter();

Model model = new Model();

model.Data.Add(new ViewModel(new Item { Id = 1 }) { IsSelected = true });
model.Data.Add(new ViewModel(new Item { Id = 2 }) { IsSelected = true });
model.Data.Add(new ViewModel(new Item { Id = 3 }) { IsSelected = false });
model.Data.Add(new ViewModel(new Item { Id = 4 }) { IsSelected = false });

presenter.Model = model;

var gateway = MockRepository.GenerateStub<IGateway>();
presenter.Gateway = gateway;

// Act
presenter.ReprocessItems();

// Assert
gateway.AssertWasCalled(o => o.ReprocessItem(1, presenter.ReprocessDone));
gateway.AssertWasCalled(o => o.ReprocessItem(2, presenter.ReprocessDone));
}

[Test]
public void ShowItemReferralCommentary()
{
// Arrange
Presenter presenter = new Presenter();

Model model = new Model();
model.Data.Add(new ViewModel(new Item { Id = 1 }) { IsSelected = true });
model.Data.Add(new ViewModel(new Item { Id = 2 }) { IsSelected = false });

presenter.Model = model;

var gateway = MockRepository.GenerateStub<IGateway>();
presenter.Gateway = gateway;

var view = MockRepository.GenerateStub<IView>();
presenter.View = view;

gateway.Stub(x => x.RequestItemCommentary(1)).Return("This is some commentary");

// Act
presenter.ShowItemReferralCommentary();

// Assert
gateway.AssertWasCalled(o => o.RequestItemCommentary(1));

view.AssertWasCalled(o => o.ShowMessageBox("This is some commentary", "Referral Commentary"));
}

[Test]
public void AcceptSelectedItems()
{
// Arrange
Presenter presenter = new Presenter();

Model model = new Model();
model.Data.Add(new ViewModel(new Item { Id = 1 }) { IsSelected = false });
model.Data.Add(new ViewModel(new Item { Id = 2 }) { IsSelected = false });
model.Data.Add(new ViewModel(new Item { Id = 3 }) { IsSelected = true });
model.Data.Add(new ViewModel(new Item { Id = 4 }) { IsSelected = true });

presenter.Model = model;

var gateway = MockRepository.GenerateStub<IGateway>();
presenter.Gateway = gateway;

// Act
presenter.AcceptSelectedItems();

// Assert
gateway.AssertWasCalled(o => o.AcceptItem(3, presenter.AcceptCompleted));
gateway.AssertWasCalled(o => o.AcceptItem(4, presenter.AcceptCompleted));
}
}

编辑:** 根据下面的评论,我通过添加 Thread.Sleep(500); 暂时解决了这个问题在每个断言之前。 Thread.Sleeps 通常是一种代码味道,我想将其锁定,但我正在努力做到 马虎 务实。如果您有更好的方法,请告诉我。

最佳答案

问题是您可能会到达测试方法的末尾,也就是您放置断言的位置,而子线程可能已经完成了它们的工作,也可能没有。在您看来,这几乎是随机的。

您可以做的,也是我在测试线程方法时所做的,是使用同步对象,例如 ManualResetEvent。您在测试方法开始时将其重置为 false:

var wait = new ManualResetEvent(false);

然后,当被测试的对象调用您的 mock 时,您设置它的状态:

Expect.Call(() => yourMock.yourMethod(whatever)).WhenCalled(x => wait.Set() );

现在,在你的断言 block 代码之前,你写一些像

Assert(wait.WaitOne(timeoutOfYourChoice));

这将为辅助线程留出足够的时间来完成它们的工作。

关于c# - Rhino Mocks AAA 语法和线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4224335/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com