东莞市连易网络科技有限公司
东莞市连易网络科技有限公司
  • 网站
  • 用户
  • 购物车
  • 购物车
  • 搜索
  • 网站
  • 用户
帮助
帮助
开发文档 单元测试
  • 用户文档
  • 开发文档
  • API文档
  • 提及
  • 标签
  • 更多
  • 取消
  • 新建
  • +开始
  • +UI 自定义
  • +外部集成
  • -插件/框架扩展
    • +插件
    • -设置开发环境
      • 依赖注入
      • 单元测试
    • +进程 API

单元测试

许多团队在开发过程中采用了某种测试自动化策略。这个概念也可以应用于Limyee 电商平台上的定制开发.

所有 Limyee 电商平台 API 都必须作为 Limyee 电商平台应用程序的一部分运行,并且不能在该进程之外执行。这意味着如果你有一个单元测试项目,它无法测试任何 Limyee 电商平台 API。虽然这看起来很奇怪,但事实并非如此。毕竟,你不应该尝试测试 Limyee 电商平台 API,而是应该测试你的代码。

Facade:封装 API

直接调用 Limyee 电商平台进程 API 或使用插件模型的定制代码都只能在 Limyee 电商平台应用程序中执行,这意味着如果业务逻辑中需要它们,则需要将它们抽象出来以测试代码,而无需调用实际的 API。

作为一种常用的开发实践,开发人员通常将业务逻辑与数据访问分开。因此,我们所有的业务规则都应用在一个服务中,而实际的数据库通信则在另一个服务中完成,逻辑服务依赖于数据服务。这是一个完美的关注点分离:业务层不关心数据的存储方式,只要它是以某种方式存储,数据层也不关心数据来自哪里。您可以将此模式与 Limyee 电商平台 API 结合使用。唯一的区别是在实现中的数据层,你不是在与数据库交互,而是在与API交互。例如,我们编写了一个组件,要求我们从数据库中获取一些用户信息。我们将通过实现 facade 来做到这一点。

步骤 1:创建您自己的用户对象

您可能想知道为什么不只使用 Limyee 电商平台版本。这是因为在 Limyee 电商平台 API 中,您可能无法实例化特定的 API 对象,并且由于它们不使用单独的接口,因此您的测试框架可能无法对其进行模拟。另一个原因是,您可能实际上并不需要所有用户的信息,因此您只公开了所需的信息。虽然这对于进程代码来说可能不是一个显著的区别,但如果您以后决定通过自定义 REST API 公开数据,则会降低有效负载。

下面是封装的 API 用户对象。请注意,在构造函数中,我们允许使用基于 API 的用户,但也允许无参数版本,以便我们可以在单元测试中使用此类。由于我们只关心我们情况中的 UserId 和 Username,这就是我们要公开的全部内容。

public class APIUser
{
   
    #region Constructors
    public APIUser()
    {
          
    }
    public APIUser(Limyee.Extensibility.Api.Entities.Version1.User coreAPIUser)
    {
        if (coreAPIUser != null)
        {
            UserId = coreAPIUser.Id;
            Username = coreAPIUser.Username;
        }
    }
    #endregion

    #region Properties
    
    public string Username{ get; set; }
    
    public int? UserId{ get; set;}
    
    #endregion
}

步骤 2:设计 Facade 接口和实现

该接口为 API 定义了我们的封装服务。使其成为一个接口意味着当我们对依赖于 API 的业务层进行单元测试时,我们可以简单地模拟这个接口,我们不再需要担心 Limyee 电商平台 API。在实现中,您可以看到此服务具有 1 个职责,调用 API 并返回预期的用户 facade,这意味着此服务的任何使用者都与 Limyee 电商平台 API 相分离。

#region Model
public interface IUsersAPIFacade
{
    APIUser GetUser(string username);
}
#endregion

#region Implementation

public class UsersAPIFacade : IUsersAPIFacade
{
    private IUsers _usersAPI = null;

    public APIUser GetUser(string username)
    {
        InitializeAPI();
        var user = _usersAPI.Get(new UsersGetOptions() {Username = username});
        if (user != null  && !user.HasErrors())
        {
            return new APIUser(user);
        }
        return null;
    }

#region API Init
    private void InitializeAPI()
    {
        if (_usersAPI == null)
            _usersAPI = Apis.Get<IUsers>();
    }
#endregion

}
#endregion

步骤 3:添加测试

我们添加了另一个简单的业务类,具体取决于我们的 API 服务。假设它有大量其他验证和逻辑,这些验证和逻辑对所阐述的概念并不重要。我们只想展示我们现在如何测试此逻辑,即使它依赖于API。

此示例使用 Moq,这是一个模拟对象的库,我们使用它来“伪造”我们的 API 服务。你可以很容易地创建一个实现我们接口的“伪造”类,虽然会随着您的测试越多越繁琐。尽管您不熟悉 Moq,但正在发生的事情非常简单。给定 IUsersAPIFacade,它要求模拟框架动态创建一个实现该接口的类,对于给定用户名的 GetUser 方法,将返回一个 APIUser,成员有:Username和 ID 为 12345。在以下情况下,我们只是告诉依赖的 API 服务返回我们想要的数据,以便测试成功,因为我们正在测试登录名对数据的反应,而不是我们如何获取数据。

#region Business Service
public class CustomUserService
{
    private IUsersAPIFacade _userApiFacade;
    public CustomUserService(IUsersAPIFacade userApiFacade)
    {
        _userApiFacade = userApiFacade;
    }

    public APIUser GetVaidatedUser(string username)
    {
        var user = _userApiFacade.GetUser(username);
        //Do some super awesome business logic that is
        //That is too secret to show you...

        return user;
    }
}
#endregion

#region Tests
public class UserTests
{
    [Test]
    public void can_get_vaidated_user()
    {
        string _userTosearch = "wally";

        var apiService = new Mock<IUsersAPIFacade>();
        apiService.Setup(s => s.GetUser(It.IsAny<string>()))
            .Returns<string>((username) =>
            {
                return new APIUser() {Username = username, UserId = 12345};
            });

        var businessService = new CustomUserService(apiService.Object);
        var foundUser = businessService.GetVaidatedUser(_userTosearch);

        Assert.AreSame(_userTosearch,foundUser.Username);
    }
}
#endregion

现在你可能会说,“如果API做错了什么,我的测试不会抓住它怎么办!你是对的,这是完全有可能的。在这种情况下,您正在测试您的业务逻辑,并且您正在向它提供数据,这些数据可能是好的还是坏的,具体取决于测试的成功方案。您不是在测试 API。该文档将为您提供有关 API 预期内容的足够信息,以便您可以适当地设置测试。假设您具有良好的测试成功率,则应用程序中的错误将意味着您的 API 层存在问题,或者您在测试中没有考虑到特点的场景。

  • 分享
  • 历史
  • 更多
  • 取消
相关
推荐
Copyright © 2021 东莞市连易网络科技有限公司. All rights reserved.
Powered by Limyee Commerce System(3.0.0). © 2014 - 2025 Limyee Inc.