gpt4 book ai didi

c# - 试图理解 MockSequence

转载 作者:太空狗 更新时间:2023-10-29 21:53:33 25 4
gpt4 key购买 nike

我目前正在编写一个应用程序,为了测试它的行为是否正确,我需要验证方法是否按给定顺序调用。

对于我的单元测试,我使用 xUnitMoq

现在,为什么我需要测试调用的顺序?

我正在开发一个在不同线程上执行任务的解决方案。一旦执行任务,我就会向给定的记录器写入一条消息,因此通过检查对记录器的调用顺序,我可以确保我的代码已正确实现。

在这里查看我正在尝试使用的代码:

public class SchedulerFixture
{
#region Constructors

public SchedulerFixture()
{
LoggerMock = new Mock<ILogger>(MockBehavior.Strict);

// Setup of other mocks removed for simplicity.
}

#endregion
}

public class SequentialTaskExecutorMock : SchedulerFixture
{
[Fact]
public void Should_WriteTheCorrectLogEntries_WhenTasksAreExecutedAndNotCancelled()
{
// Defines the task that needs to be executed.
var task = new LongRunningServiceTaskImplementation();

// Built a sequence in which logs should be created.
var sequence = new MockSequence();

LoggerMock.Setup(x => x.Information(It.IsAny<string>(), It.IsAny<string>())).Verifiable();

LoggerMock.InSequence(sequence).Setup(x => x.Information("émqsdlfk", "smdlfksdmlfk")).Verifiable();
LoggerMock.InSequence(sequence).Setup(x => x.Information(LoggingResources.LoggerTitle, LoggingResources.Logger_ServiceStopped)).Verifiable();
LoggerMock.InSequence(sequence).Setup(x => x.Information(LoggingResources.LoggerTitle, LoggingResources.Logger_ServiceStarted)).Verifiable();
LoggerMock.InSequence(sequence).Setup(x => x.Information(LoggingResources.LoggerTitle, string.Format(CultureInfo.InvariantCulture, LoggingResources.Logger_TaskCompleted, task.TaskName))).Verifiable();
LoggerMock.InSequence(sequence).Setup(x => x.Information(LoggingResources.LoggerTitle, LoggingResources.Logger_ServiceStopped)).Verifiable();

// Setup the mock required for the tests.
TaskGathererMock.Setup(x => x.GetServiceTasks(LoggerMock.Object)).Returns(() =>
{
return new[] { task };
});

// Start the scheduler.
Scheduler.Start(TaskGathererMock.Object, ConfigurationManagerMock.Object);

// Wait for 5 seconds (this simulates running the service for 5 seconds).
// Since our tasks execution time takes 4 seconds, all the assigned tasks should have been completed.
Thread.Sleep(5000);

// Stop the service. (We assume that all the tasks have been completed).
Scheduler.Stop();

LoggerMock.VerifyAll();
}
}

因此,我测试的第一步是设置日志,然后执行测试本身(这会调用记录器),最后我会验证它。

但是,测试总是通过。

在这种情况下它应该失败,因为下面的调用:

LoggerMock.InSequence(sequence).Setup(x => x.Information("émqsdlfk", "smdlfksdmlfk")).Verifiable();

没有在我的代码中的任何地方执行。

最佳答案

虽然这确实感觉像是 Moq 中的错误(请参阅 Patrick Quirk 对该问题的第一条评论),但这里有一个粗略的想法,您可以改为执行此操作。这是一种“长评论”。

创建一个简单的类:

class SequenceTracker
{
int? state;

public void Next(int newState)
{
if (newState <= state)
Assert.Fail("Bad ordering there! States should be increasing.");

state = newState;
}
}

然后像这样使用它(你自己的代码的修改版本):

public void Should_WriteTheCorrectLogEntries_WhenTasksAreExecutedAndNotCancelled()
{
// Defines the task that needs to be executed.
var task = new LongRunningServiceTaskImplementation();

// USE THE CLASS I PROPOSE:
var tracker = new SequenceTracker();


//LoggerMock.Setup(x => x.Information(It.IsAny<string>(), It.IsAny<string>()))

LoggerMock.Setup(x => x.Information("émqsdlfk", "smdlfksdmlfk"))
.Callback(() => tracker.Next(10));
LoggerMock.Setup(x => x.Information(LoggingResources.LoggerTitle, LoggingResources.Logger_ServiceStopped))
.Callback(() => tracker.Next(20));
LoggerMock.Setup(x => x.Information(LoggingResources.LoggerTitle, LoggingResources.Logger_ServiceStarted))
.Callback(() => tracker.Next(30));
LoggerMock.Setup(x => x.Information(LoggingResources.LoggerTitle, string.Format(CultureInfo.InvariantCulture, LoggingResources.Logger_TaskCompleted, task.TaskName)))
.Callback(() => tracker.Next(40));
LoggerMock.Setup(x => x.Information(LoggingResources.LoggerTitle, LoggingResources.Logger_ServiceStopped))
.Callback(() => tracker.Next(50));

// Setup the mock required for the tests.
TaskGathererMock.Setup(x => x.GetServiceTasks(LoggerMock.Object)).Returns(() =>
{
return new[] { task };
});

// Start the scheduler.
Scheduler.Start(TaskGathererMock.Object, ConfigurationManagerMock.Object);

// Wait for 5 seconds (this simulates running the service for 5 seconds).
// Since our tasks execution time takes 4 seconds, all the assigned tasks should have been completed.
Thread.Sleep(5000);

// Stop the service. (We assume that all the tasks have been completed).
Scheduler.Stop();

// THIS NOW WORKS BECAUSE WE ABANDONED THE 'MockSequence' APPROACH:
LoggerMock.VerifyAll();
}

当然,如果需要,这可以做得更高级。

关于c# - 试图理解 MockSequence,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32585355/

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