C# Moq用于验证不可预测的特定值
为了便于解释,我有以下代码C# Moq用于验证不可预测的特定值,c#,unit-testing,moq,C#,Unit Testing,Moq,为了便于解释,我有以下代码 public interface IAnother { void DoAnotherJob(DateTime date); } public class MainJob { private IAnother another; public MainJob(IAnother another) { this.another = another; } public void FunctionA()
public interface IAnother
{
void DoAnotherJob(DateTime date);
}
public class MainJob
{
private IAnother another;
public MainJob(IAnother another)
{
this.another = another;
}
public void FunctionA()
{
this.FunctionB(DateTime.Now);
}
public void FunctionB(DateTime date)
{
this.another.DoAnotherJob(date);
}
}
我需要编写一个单元测试代码,以确保何时调用function()
底层IAnother.DoAnotherJob()
以使用当前日期时间
我可以编写测试代码
[TestMethod()]
public void FunctionATest()
{
var mockAnother = new Mock<IAnother>();
var mainJob = new MainJob(mockAnother.Object);
mainJob.FunctionA();
mockAnother.Verify(x => x.DoAnotherJob(It.IsAny<DateTime>()), Times.Once);
}
[TestMethod()]
公开考试
{
var mockother=new Mock();
var mainJob=新的mainJob(mockother.Object);
mainJob.function();
mockother.Verify(x=>x.DoAnotherJob(It.IsAny()),Times.Once);
}
为了确保使用任何日期时间调用该函数,我无法指定确切的值,因为DateTime
的实际值是不可预测的
有什么想法吗?当您想要验证与
DateTime有关的任何内容时,总是会遇到困难。现在,属性值很可能在调用之间发生变化。您所能做的最好的事情如下:
mockAnother.Verify(x => x.DoAnotherJob(It.Is<DateTime>(d > DateTime.Now.AddSeconds(-1))), Times.Once);
然后您将使用它来代替日期时间。现在直接使用
:
public class MainJob
{
private IAnother another;
private ITimeProvider timeProvider;
public MainJob(IAnother another, ITimeProvider timeProvider)
{
this.another = another;
this.timeProvider = timeProvider;
}
public void FunctionA()
{
this.FunctionB(this.timeProvider.Now);
}
public void FunctionB(DateTime date)
{
this.another.DoAnotherJob(date);
}
}
然后,单元测试变成:
[TestMethod()]
public void FunctionATest()
{
var now = DateTime.Now;
var mockAnother = new Mock<IAnother>();
var mockTimeProvider = new Mock<ITimeProvider>();
mockTimeProvider.Setup(x => x.Now).Returns(now);
var mainJob = new MainJob(mockAnother.Object, mockTimeProvider.Object);
mainJob.FunctionA();
mockAnother.Verify(x => x.DoAnotherJob(now), Times.Once);
}
[TestMethod()]
公开考试
{
var now=DateTime.now;
var mockother=new Mock();
var mockTimeProvider=new Mock();
mockTimeProvider.Setup(x=>x.Now).Returns(Now);
var mainJob=新的mainJob(mockother.Object,mockTimeProvider.Object);
mainJob.function();
mockother.Verify(x=>x.doatherjob(现在),Times.Once);
}
Roy Osherove在(第134页)中建议使用一个SystemTime
类,该类提供.Now
和一种测试方法来设置.Now
返回的内容。从这里开始,就是要确保所有的东西都使用这个类。回答得好。我想我会把你的第一个建议作为我的方法,因为我总是认为仅仅为了处理DateTime而引入一些东西太沉重了。现在,我打赌构建服务器的运行速度足够快,可以在x秒内执行测试用例。
[TestMethod()]
public void FunctionATest()
{
var now = DateTime.Now;
var mockAnother = new Mock<IAnother>();
var mockTimeProvider = new Mock<ITimeProvider>();
mockTimeProvider.Setup(x => x.Now).Returns(now);
var mainJob = new MainJob(mockAnother.Object, mockTimeProvider.Object);
mainJob.FunctionA();
mockAnother.Verify(x => x.DoAnotherJob(now), Times.Once);
}