最近,我正在学习单元测试,并尝试在我的项目中使用此技能。 但是,我对如何测试以下代码有一些疑问。
public class Class1
{
private Timer _timer = new Timer();
public Class1()
{
_timer.Interval = 1000;
_timer.Elapsed += _timer_Elapsed;
}
private void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
//some works
}
public void start()
{
_timer.Start();
//some works
}
public void stop()
{
_timer.Stop();
//some works
}
}
我真的不知道如何在不破坏其封装的情况下测试此类。
我应该公开'_timer_Elapsed'方法吗?如果埃文这样做,那么下一个问题是如何测试方法“开始”和“停止”。我是否应该使用存根对象替代Timer以便测试此类?如果那样的话,该类将太复杂,因为我需要创建一个接口,并创建一个封装Timer并实现上述接口的类。
public interface IEncal
{
double Interval { get; set; }
event ElapsedEventHandler Elapsed;
void Stop();
void Start();
}
public class MyClass : IEncal
{
Timer timer = new Timer();
public double Interval { get { return timer.Interval; } set { timer.Interval = value; } }
public event ElapsedEventHandler Elapsed
{
add { timer.Elapsed += value; }
remove { timer.Elapsed -= value; }
}
public void Start()
{
timer.Start();
}
public void Stop()
{
timer.Stop();
}
}
public class Class1
{
private IEncal _timer;
public Class1(IEncal timer)
{
_timer = timer;
_timer.Interval = 1000;
_timer.Elapsed += _timer_Elapsed;
}
public void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
//some works
}
public void start()
{
_timer.Start();
//some works
}
public void stop()
{
_timer.Stop();
//some works
}
}
有没有更好的方法来测试此类?
以下是我使用的真实代码。 我已经为ISender类和IInfoProducer类编写了单元测试。 由于这是我第一次使用单元测试,因此我想考虑一下每个要学习的课程。
回到问题所在,此类基本上是一个Timer类。在流失时, 它发送一个信息。那么我应该如何测试此定时发送过程?
public class InfomationSender
{
private readonly Timer _timer = new Timer();
private readonly ISender _sender;
private readonly IInfoProducer _producer;
public InfomationSender(ISender sender, IInfoProducer producer)
{
_sender = sender;
_producer = producer;
_timer.Interval = 1000;
_timer.Elapsed += _timer_Elapsed;
}
private void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
var info = _producer.getInfo();
_sender.send(info);
}
public void start()
{
_timer.Start();
}
public void stop()
{
_timer.Stop();
_sender.Dispose();
}
}
答案 0 :(得分:1)
您应该能够测试类而不进行模拟。减少嘲笑会更有价值。
但是您没有提供有关代码在// some works
区域中所做的工作的信息。因为这是您要测试的内容,所以计时器只是实现细节。
对于测试“某些作品”类,应该提供对“某些作品”结果的一些公共访问,否则结果将通过注入的依赖项(存储库,记录器等)“公开”
假设类将每秒执行“一些工作”,并在调用Result
方法之后更新Stop
属性。
public class LiveCalculator
{
private readonly Timer _timer;
private List<int> _allValues
private int _lastSum;
public int LastSum => _lastSum;
public LiveCalculator()
{
_allValues = new List<int>();
_timer = new Timer { Interval = 1000 };
_timer.Elapsed += _timer_Elapsed;
}
private void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
_allValues.Add(42);
}
public void start()
{
_timer.Start();
}
public void stop()
{
_timer.Stop();
_lastResult = _allValues.Sum();
}
}
测试
[Fact]
public async Task AfterFiveSeconds_LastResultEquals210()
{
var calculator = new LiveCalculator();
calculator.Start();
await Task.Delay(5100);
calculator.Stop();
calculator.LastResult.Should().Be(210);
}