使用NUnit和Moq对事件进行单元测试的更好方法
本文关键字:单元测试 更好 方法 事件 NUnit Moq 使用 | 更新日期: 2023-09-27 18:00:48
我正在使用NUnit和Moq来测试一个包含一些事件的类,并试图找到测试事件是否被激发的最佳方法。我想出了这个解决方案,但感觉有点脏,因为我必须为测试创建一个接口。有什么办法可以用更少的代码做同样的事情,或者不必创建接口?
这并没有那么糟糕,但我觉得有人可能有更好的解决方案。欢迎提出任何想法。谢谢
[Test]
public void StartedAndStoppedEventsShouldFireWhenStartedAndStopped()
{
var mockStartedEventSubscriber = new Mock<IEventSubscriber>();
var mockStoppedEventSubscriber = new Mock<IEventSubscriber>();
_NetworkMonitor.Started += mockStartedEventSubscriber.Object.Handler;
_NetworkMonitor.Stopped += mockStoppedEventSubscriber.Object.Handler;
_NetworkMonitor.Start();
_NetworkMonitor.Stop();
Func<bool> func = () => { return (eNetworkMonitorStatus.Stopped == _NetworkMonitor.Status); };
Utilities.WaitUntilTrue(func, _NetworkMonitor.Interval * 2, 10);
_NetworkMonitor.Started -= mockStartedEventSubscriber.Object.Handler;
_NetworkMonitor.Stopped -= mockStoppedEventSubscriber.Object.Handler;
mockStartedEventSubscriber.Verify(h => h.Handler(_NetworkMonitor, EventArgs.Empty), Times.Once());
mockStoppedEventSubscriber.Verify(h => h.Handler(_NetworkMonitor, EventArgs.Empty), Times.Once());
}
public interface IEventSubscriber
{
void Handler(object sender, EventArgs e);
}
没有mock,这个测试似乎更容易完成。使测试夹具兼作事件订阅者。
_networkMonitor.Started += this.SetStartedFlag; // a private method which sets a flag in the test fixture.
_networkMonitor.Start();
Assert.That(StartedFlag, Is.True);
我认为,您根本不需要moq。您只需注册事件并评估它们是否已被激发(或被激发的次数):
public class NetworkMonitor
{
public event EventHandler Started;
public event EventHandler Stopped;
public void Start()
{
var handler = Started;
if (handler != null)
handler(this, EventArgs.Empty);
}
public void Stop()
{
var handler = Stopped;
if (handler != null)
handler(this, EventArgs.Empty);
}
}
[Test]
public void StartedAndStoppedEventsShouldFireWhenStartedAndStopped()
{
NetworkMonitor classUnderTest = new NetworkMonitor();
bool startedWasFired = false;
int stoppedWasFired = 0;
classUnderTest.Started += (o, e) => { startedWasFired = true; };
classUnderTest.Stopped += (o, e) => { stoppedWasFired++; };
classUnderTest.Start();
Assert.That(startedWasFired);
classUnderTest.Stop();
Assert.That(stoppedWasFired, Is.EqualTo(1));
}
下面是我过去使用的一种方法的片段,效果很好。它只是将ConnectionChangedEventArgs的实例添加到List<>每次触发事件时。然后断言有多少事件被触发。希望你能得到这个想法,如果你愿意的话,可以根据自己的需求进行调整。
[Test]
public void GoodConnectionRaisesConnectionChangedEvent()
{
const int EXPECTED = 1;
List<ConnectionChangedEventArgs> ev = new List<ConnectionChangedEventArgs>();
// Mocks and setup stuff here...
using (PlcController pc = new PlcController(mock.Object))
{
pc.ConnectionChanged += delegate(object sender, ConnectionChangedEventArgs e)
{
ev.Add(e);
};
pc.Connect();
}
Assert.That(ev.Count, Is.EqualTo(EXPECTED));
}