最近在学习单元测试,想把这个技能运用到我的项目中。 但是,我对如何测试以下代码有一些疑问。
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”方法吗? Evan 如果这样做,下一个问题是如何测试方法“开始”和“停止”。我应该使用 stub 对象来代替定时器来测试这个类吗?如果那样的话,这个类就太复杂了,因为我需要制作一个接口(interface)并制作一个类来封装 Timer 并实现上面的接口(interface)。
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();
}
}
最佳答案
您应该能够在不模拟的情况下测试该类。更少的 mock 更有值(value)的测试。
但是您没有提供有关您的代码在 //some works
区域中执行的操作的信息。因为这是你要测试的,定时器只是实现细节。
为了测试“一些作品”,类应该提供一些对“一些作品”结果的公共(public)访问,否则结果将通过注入(inject)的依赖项(存储库、记录器等)“暴露”
假设类将每秒执行“一些工作”并在调用 Stop
方法后更新 Result
属性。
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);
}
关于c# - 关于单元测试的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54661627/