【问题标题】:faking API calls /w NSubstitute, for unit testing伪造 API 调用 /w NSubstitute,用于单元测试
【发布时间】:2016-09-08 16:04:42
【问题描述】:

我有很多函数调用,比如下面的函数调用,我想对其进行单元测试,但不确定我应该如何处理这些函数。 我只是用真实的 URL 和 API 调用来测试它吗?但是它不会是一个真正的单元测试,因为我包括了我无法控制的东西......这导致我得出结论,我必须模拟 RestClient 出来?我需要在哪里制作一个RestClient Foo(ApiUrl + ApiDirectory);,我可以在上面使用NSubtitute,这是正确的方法吗??

你们会以同样的方式处理它吗?还是有一个聪明的方法来做这个单元测试?

// ReSharper disable once InconsistentNaming
public IRestResponse TCAPIconnection( Method b, long c = 0, object d = null)
{
    var client = c == 0 ? new RestClient(ApiUrl + ApiDirectory) : new RestClient(ApiUrl + ApiDirectory + c);
    var request = new RestRequest(b);
    request.AddHeader("Authorization", Token);
    if (d != null)
    {
        request.AddJsonBody(d);
    }
    var response = client.Execute(request);
    return response;
}

【问题讨论】:

    标签: c# unit-testing nunit nsubstitute


    【解决方案1】:

    您提供的方法不会在更大的系统上运行,并且您实际上会更改原始代码以进行测试。

    模拟框架通常用于单元测试。单元测试本身只是功能的一小部分,一种方法。它绝对不涉及服务。

    你应该追求的是抽象,你可以简单地模拟你的服务使用的interface

    让我们考虑一个简短的例子。你有一个 IBluetoothService 被注入到 BluetoothManager 类中。该接口会暴露一些在测试模式下会被模拟的方法。

    public interface IBluetoothService
    {
        object GetData();
        bool SendData(object request);
    }
    
    public class BluetoothAPI : IBluetoothService
    {
        public object GetData()
        {
            // API logic to get data.
            return new object();
        }
    
        public bool SendData(object request)
        {
            // API logic to send data.
            return false;
        }
    }
    

    在您的Loggerconstructor 中,您应该注入IBluetoothService

    public class Logger
    {
        private readonly IBluetoothService _bluetoothService;
        public Logger(IBluetoothService bluetoothService)
        {
            _bluetoothService = bluetoothService;
        }
    
        public void LogData(string textToLog)
        {
            if (!_bluetoothService.SendData(textToLog))
                throw new ArgumentException("Could not log data");
        }
    }
    

    因此,既然您在应用程序中实现了这个抽象级别,您就可以有效地开始对其进行测试。

    public void SmokeTest()
    {
        var substitute = Substitute.For<IBluetoothService>();
        substitute.GetData().Returns(1);
        // Swap true with false and test will fail.
        substitute.SendData(Arg.Any<object>()).Returns(true);
        var sut = new Logger(substitute);
        try
        {
            sut.LogData("Some data to log");
        }
        catch (ArgumentException ex)
        {
            Assert.Fail("Mocked API call returned wrong value.");
        }
    }
    

    NSubstitute 是一个强大的工具,如果您的应用程序具有正确的架构,它可以让您测试所有内容。要获得可测试的代码,您几乎不需要任何东西,只需注入 interface。这不仅让您在软件开发中拥有可测试而且更易于维护的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-11
      • 1970-01-01
      相关资源
      最近更新 更多