Web Atoms

Simple Unit Testing with Web Atoms

akashkava profile image Akash Kava ・2 min read

Test Class and Method

I know many would be unhappy seeing classes, but classes are only used to decorate and organize code, you can always do more functional things with Web Atoms Unit Tests.

/** Category decorator is optional, it just lets you specify name of test instead of name of class that extends TestItem */
@Category("Test Case 1")
export default class TestCase1 extends TestItem {

    public parseTest() {
        Assert.equals(2, parseInt("2", 10));

    /** You can specify name of test */
    @Test("Parse Float Test")
    public parseFloat() {
        Assert.equals(2.5, parseFloat("2.5"));


How to run the test?

You can execute @web-atoms/unit-test/index.js script against folder of all scripts. You can also give path to single test file as well.

d:\git\test> node ./node_modules/@web-atoms/unit-test/index.js ./dist

Test Case 1 > parseTest success.
Test Case 1 > Parse Float Test success.

Async Tests

Your test method can also return Promise and it unit test engine will await for the result.

@Category("Async Test 1")
export default class TestCase1 extends TestItem {

    public async asyncTestOne() {
        const p = method that returns Promise ....
        await p;


Global Separation

Each unit test executes in a separate Global context in Node, this isolates every unit test method. Even same test methods in same class do not share same context.

declare var global: any;

export default class TestCase1 extends TestItem {

    public async parseTest() {
        global.a = 1;
        await Atom.delay(100);
        Assert.equal(1, global.a);

    public async parseTest2() {
        global.a = 2;
        await Atom.delay(50);
        Assert.equal(2, global.a);


Both tests will be successful.

How to test ViewModel?

Since AtomViewModel requires dependency injection, we have created a class AtomTest which sets up dependency injection with Mock Service Container.

This class contains app and it has a method waitForPendingCalls which allows you to wait for all pending initializations.

class TestVM extends AtomViewModel {

   public movies: IMovie[];

   public search: string = null;

   @Inject private movieService: MovieService;

   /** This will be executed when vm is initialized and it will
    * be executed when search will be updated 
   @Load({ init: true, watch: true })
   public async loadItems(ct: CancelToken) {
      const s = this.search;
      this.movies = await this.movieService.loadMovies(s, ct);


export default class TestVMCase extends AtomTest {

    public async vmTest() {
        // this waits till loading of vm is complete
        const vm = await this.createViewModel(TestVM);
        Assert.equals(5, vm.movies.length);

        // lets update search
        vm.search = "a";

        // lets wait for few milliseconds
        // and we assume that mock will populate
        // results...
        await Atom.delay(100);
        Assert.equals(1, vm.movies.length);



Every dependency can specify mock as shown below.

@DISingleton({ mock: "./mocks/MockMovieService" })
export default class MovieService extends BaseService {

    public async loadMovies(
        @Query("search") search: string,
        ct: CancelToken) {
        return null;


export default class MockMovieService {

    public async loadMovies(
        search: string,
        ct: CancelToken) {
        // create artificial delay...
        await Atom.delay(1);
        if (ct.cancelled) throw new Error("cancelled");
        return [
           ... movies 

Posted on by:

Web Atoms

TSX instead of Xaml, TypeScript instead of C#, Hot reload Xamarin.Forms published App, use VS Code for Xamarin.Forms Development.... "Web Atoms" is an advanced MVVM framework to write cross platform applications in HTML5 and Xamarin.Forms.


markdown guide