gpt4 book ai didi

c# - 如何对涉及 SynchronizationContext 的代码进行单元测试?

转载 作者:太空狗 更新时间:2023-10-30 00:44:15 24 4
gpt4 key购买 nike

我尝试使用 NUnit 和 Rhino 模拟测试以下代码。

void _tracker_IndexChanged(object sender, IndexTrackerChangedEventArgs e)
{
// _context is initialised as
// SynchronizationContext _context = SynchronizationContext.Current;
// _tracker.Index is stubbed to return the value 100
_context.Post(o => _view.SetTrackbarValue(_tracker.Index), null);
}

在测试用例中,我将期望设置为

_view.Expect(v => v.SetTrackbarValue(100));

当我验证预期时,单元测试随机失败并显示消息

Test(s) failed. Rhino.Mocks.Exceptions.ExpectationViolationException :
IIndexTrackerView.SetTrackbarValue(100); Expected #1, Actual #0.

我没能确定这里的问题,我该如何解决?

最佳答案

我通常通过使用可以实例化和模拟的抽象类或接口(interface)封装全局状态来解决此类问题。然后我不直接访问全局状态,而是将我的抽象类或接口(interface)的实例注入(inject)到使用它的代码中。

这让我可以模拟全局行为,并使我的测试不依赖于或执行不相关的行为。

这是您可以做到这一点的一种方法。

public interface IContext
{
void Post(SendOrPostCallback d, Object state);
}

public class SynchronizationContextAdapter : IContext
{
private SynchronizationContext _context;

public SynchronizationContextAdapter(SynchronizationContext context)
{
_context = context;
}

public virtual void Post(SendOrPostCallback d, Object state)
{
_context.Post(d, state);
}
}

public class SomeClass
{
public SomeClass(IContext context)
{
_context = context;
}

void _tracker_IndexChanged(object sender, IndexTrackerChangedEventArgs e)
{
_context.Post(o => _view.SetTrackbarValue(_tracker.Index), null);
}
// ...
}

然后您可以模拟或 stub IContext,这样您就不必担心线程问题,并且可以使用仅执行委托(delegate)的简单实现。

如果我编写单元测试来模拟它,我还会编写更高级别的“集成”测试,这些测试不会模拟它,但验证的粒度更小。

关于c# - 如何对涉及 SynchronizationContext 的代码进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8353950/

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