伪造 API 调用/w NSubstitute,用于单元测试 [英] faking API calls /w NSubstitute, for unit testing
问题描述
我收到了很多像下面这样的函数调用,我想对其进行单元测试,但不确定我应该如何处理这些函数.我只是用真实的 URL 和 API 调用来测试它吗?但是它不会是真正的单元测试,因为我包含了我无法控制的东西......这使我得出结论,我必须模拟 RestClient
出来?我需要制作一个 RestClient Foo(ApiUrl + ApiDirectory);
,我可以在上面使用 NSubtitute
,这是正确的方法吗??
I got a lot of function calls like the one below that I want to unit test but are unsure of how i should approach functions like these..
Do I just test it with the real URL and API calls?? but then it won't be a real unit test since I including things which I don't have control of... which leads me to the conclusion that I have to mock the RestClient
out?? where I need to make a RestClient Foo(ApiUrl + ApiDirectory);
which I can use NSubtitute
on, is it the right way??
你们会以同样的方式处理它吗?或者有没有聪明的方法来做这个单元测试?
Would you guys approach it the same way? or is there a smart way do this unit test?
// 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;
}
推荐答案
您提供的方法不会在规模更大的系统上运行,而您实际上为了测试目的而更改了原始代码.
Your provided approach is not going to fly on a greater in size system as well as you actually alter your original code for testing purposes.
模拟框架通常用于单元测试.单元测试本身只是功能的一小部分,一种方法.它绝对不涉及服务.
Mocking frameworks are generally used for unit-testing. Unit test in itself is just a small fraction of functionality, a single method. It most definitely do not involve services.
您应该追求的是抽象,您可以在其上简单地模拟您的服务使用的 interface
.
What you should be going for is abstractions upon which you can simply mock an interface
which your services use.
让我们考虑一个简短的例子.您有一个 IBluetoothService
,它被注入到 BluetoothManager
类中.该接口将公开一些在测试模式下将被模拟的方法.
Lets consider a short example. You have a IBluetoothService
which is being injected into BluetoothManager
class. The interface would expose few methods which on the test mode will be mocked.
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
类 constructor
中,您应该注入 IBluetoothService
.
In your Logger
class constructor
you should inject 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");
}
}
因此,既然您在应用程序中使用了这种抽象级别,您就可以有效地开始对其进行测试.
So since you got this abstraction level going in your application you effectively start testing it.
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
.这不仅让您在软件开发中拥有可测试且更易于维护的方法.
NSubstitute
is a powerful tool which allows you to test everything if you have the correct architecture in you application. To achieve a testable code you need little to nothing, just inject interface
. This does not only allow you to have a testable but also more maintainable approach in software development.
这篇关于伪造 API 调用/w NSubstitute,用于单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!