最小起订量以验证某些不可预测的值
Moq to verify certain value not predicable
为了方便解释,我有以下代码
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);
}
}
我需要编写单元测试代码以确保在调用 FunctionA()
时底层 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);
}
确保函数在任何日期时间被调用,但我无法指定确切的值,因为 DateTime
的实际值不可预测。
有什么想法吗?
当您想要验证有关 DateTime.Now
的任何内容时,您总是会遇到困难,因为 属性 值很可能会在两次调用之间发生变化。你能做的最好的事情是这样的:
mockAnother.Verify(x => x.DoAnotherJob(It.Is<DateTime>(d > DateTime.Now.AddSeconds(-1))), Times.Once);
另一种方法是引入另一个 class 和用于解析 DateTime
:
的抽象
public interface ITimeProvider
{
DateTime Now { get; }
}
public class TimeProvider : ITimeProvider
{
DateTime Now { get { return DateTime.Now ; } }
}
然后您将直接使用而不是 DateTime.Now
:
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);
}
为了方便解释,我有以下代码
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);
}
}
我需要编写单元测试代码以确保在调用 FunctionA()
时底层 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);
}
确保函数在任何日期时间被调用,但我无法指定确切的值,因为 DateTime
的实际值不可预测。
有什么想法吗?
当您想要验证有关 DateTime.Now
的任何内容时,您总是会遇到困难,因为 属性 值很可能会在两次调用之间发生变化。你能做的最好的事情是这样的:
mockAnother.Verify(x => x.DoAnotherJob(It.Is<DateTime>(d > DateTime.Now.AddSeconds(-1))), Times.Once);
另一种方法是引入另一个 class 和用于解析 DateTime
:
public interface ITimeProvider
{
DateTime Now { get; }
}
public class TimeProvider : ITimeProvider
{
DateTime Now { get { return DateTime.Now ; } }
}
然后您将直接使用而不是 DateTime.Now
:
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);
}