c# - 关于单元测试的问题

标签 c# unit-testing

最近在学习单元测试,想把这个技能运用到我的项目中。 但是,我对如何测试以下代码有一些疑问。

 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/

相关文章:

c# - 如何配置 Visual Studio 来执行 HTML5 标准?

c# - 如何为 IGrouping 设置 NUnit 模拟对象

java - 检查元素是否验证条件

java - 如何模拟对从 protected 资源继承的接口(interface)的调用

c# - 了解 linq 语法

c# - FirstOrDefault 抛出 'Sequence contains more than one matching element'

c++ - 是否可以将 TDD 与图像处理算法一起使用?

unit-testing - AngularJs : triggering an event to simulate user action when unit testing a directive

c# - 为什么异步 LINQ Select lambda 不需要返回值

c# - 为什么 IObservable<T>.First() 会阻塞?