SAP Spartacus 单元测试开发规范

所有代码都必须被单元测试覆盖。

每次测试测试一件事(在一个 it 里实现)。

单元测试将被测试的代码与其依赖项隔离:模拟所有的依赖项。

单元测试需要相互独立:我们应该能够以任何顺序从文件运行测试,并且不会改变结果。

在适用时涵盖快乐路径、错误、边缘情况和 UI。

UI Components

Mock Everything

与任何其他代码段一样,我们希望单独测试 UI 组件。 我们不希望测试结果受到我们正在测试的类之外的代码的影响。


虽然模拟服务之类的依赖关系更为明显,但很容易忘记模拟从测试组件的模板中调用的子组件。


要模拟子组件,您可以在规范文件中创建它的假副本。 伪造组件必须与您要伪造的子组件具有相同的选择器:


例子:

@Component({
  template: '',
  selector: 'cx-some-component'
})
class MockSomeComponent {
  @Input() someparam;
}

Then, you declare it in the TestBed:

TestBed.configureTestingModule({
    imports: [
        ...
    ],
    declarations: [MockSomeComponent],
    providers: [
        ...
    ],
}).compileComponents();

NGRX and Tests That Use the Store

事实证明,模拟 NGRX 商店是一项相当大的挑战。 NGRX 存储是我们单元测试中模拟依赖项规则的例外。


要对从 store 读取的一段代码执行单元测试,请通过使用数据显式调用相关成功操作来填充 store 以设置测试。


这是我们调度 LoadUserAddressesSuccess 来设置测试数据的示例:

it('should be able to get user addresses', () => {
  const mockUserAddresses: Address[] = [{ id: 'address1' }, { id: 'address2' }];
  store.dispatch(new UserActions.LoadUserAddressesSuccess(mockUserAddresses));

  let addresses: Address[];
  service
    .getAddresses()
    .subscribe(data => {
      addresses = data;
    })
    .unsubscribe();
  expect(addresses).toEqual([{ id: 'address1' }, { id: 'address2' }]);
});

Avoiding Silently Failing Tests

最好的做法是删除订阅之外的断言。 这样,我们确保在测试完成之前执行断言。 为了断言 observable 的结果,我们在订阅中分配结果,但断言是在订阅之外用值完成的。

下列做法不推荐:

service
      .getAddresses()
      .subscribe(addresses => {
        expect(addresses).toEqual([{ id: 'address1' }, { id: 'address2' }]);
      })
      .unsubscribe();

  });
上一篇:一些SAP Partners能够通过二次开发实现打通 SAP C/4HANA和S/4HANA 的场景分享


下一篇:[nodemon] Error: watch /xxx/ ENOSPC 解决方法