1

如果接口实现中使用的事件未出现在您正在模拟的接口中,是否有办法使用 moq 对引发事件进行单元测试?

注意:我的界面与我的 UI 没有任何关系,我的事件仅用于 UI 通知,因此我想将该行为与实际界面分离,因为存储库位于与客户端/UI 不同的库中。

例如:

    [Test]
    public void TestRaiseBarProcessed()
    {
        ManualResetEvent barProcessedEvent = new ManualResetEvent(false);
        bool called = false;

        //Arrange
        Mock<IFooRepository> mockFooRepository = new Mock<IFooRepository>();

        mockSourceRepository
            .Setup(a => a.SearchForBar(barsToFind))
            .Returns(barsFound)
            .Raises(
                a => a.BarProcessed += null, 
                new BarFoundEventArgs(It.IsAny<string>()));

        IList<IFooRepository> mockFooRepositories = 
            new List<IFooRepository>();

        mockFooRepositories.Add(mockFooRepository.Object);

        FooBar fooBar = new FooBar(mockFooRepositories, FooList);

        fooBar.CurrentBarBeingProcessedInfo += (sender, e) =>
            {
                barProcessedEvent.Set();
                called = true;
            };

        //Act
        fooBar.CallFooRepositoryMethod();

        barProcessedEvent.WaitOne(25, false);

        //Assert
        mockFooRepository.Verify(
            a => a.SearchForBar(barsToFind),
            Times.Once());

        Assert.AreEqual(true, called);
    }

让我知道这是否需要更多澄清。

4

1 回答 1

0

您是否考虑过在另一个界面中定义该仅 UI 事件并实现它们?如果是这样,您可以使用 Moq 的多界面模拟:

var fooRepositoryMock = new Mock<IFooRepository>();
var barUiEventMock = fooRepositoryMock.As<IBarUiEvent>();
bool wasCalled = false;
barUiEventMock.Object.BarProcessed += (s, e) => wasCalled = true;

fooRepositoryMock
    .Setup(m => m.SearchForBars(barsToFind))
    .Returns(barsFound)
    .Raises(
        foo => barUiEventMock.Object.BarProcessed += null,
        new BarFoundEventArgs("")
    );

// ...

Assert.That(wasCalled, Is.True);

调用SearchForBars将导致BarProcessed使用您传递的任何参数引发事件。

于 2012-09-26T15:41:33.993 回答