伪造 API 调用 /w NSubstitute,用于单元测试

faking API calls /w NSubstitute, for unit testing

我收到了很多像下面这样的函数调用,我想对其进行单元测试,但不确定我应该如何处理这些函数.. 我只是用真正的 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;
}

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

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

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

让我们考虑一个简短的例子。你有一个 IBluetoothService 被注入 BluetoothManager class。该接口将公开一些在测试模式下将被模拟的方法。

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;
    }
}

在你的 Logger class constructor 你应该注入 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。这不仅可以让您在软件开发中拥有可测试而且更易于维护的方法。