Sample Jasmine Canonical Test


#1

The following is a sample template for writing a canonical jasmine test. This is the method of choice if you are developing on a remote environment. If you are developing on a local, docker-hosted environment, then The Canonical Test Runner is the preferred method of writing tests for Canonicals. (See full length documentation article on Canonical Test Runner here: https://YOUR_ENVIRONMENT.c3iot.ai/api/1/YOUR_TENANT/YOUR_TAG/documentation/topic/canonical-tests

The following file is not executable. It must be filled in with your canonical’s specific Type names and logic. It is recommended that you implement test for all fields you are transforming, to each destination c3Type they are being transformed to. It is also recommended that Transform conditions be tested as well.

var filename = "test_TransformTemplate";

describe(filename, function () {
  /**
   * Setup the test
   */
  beforeAll(function () {
    this.ctx = TestApi.createContext(filename);

    // CanonicalName will be the name of the Canonical File you are testing.  
    // cField# will represent a the field name on the Canonical File that you wish to test the Tranform for.
    // value# will represent the value of the cField, think of the value in the column of the csv file in a given row.

    // here, we now create a couple Canonical Entries, more or less simulating a file load event to a given Canonical.  
    this.canonical1 = CanonicalName.make({
      cField1: "value1",
      cField2: "value2",
      cField3: "value3"
    });

    this.canonical2 = CanonicalName.make({
      cField1: "value4",
      cField2: "value5",
      cField4: "value6"
    });


    // Now, we process the two Canonical entries that we created above.
    // This will put entries in the Data Load Queue, hence the waitForSetup() call.

    CanonicalName.process([this.canonical1, this.canonical2]);
    TestApi.waitForSetup(this.ctx, null, 1, 60);
  });

  it("transforms CanonicalName to some TypeName1 via some Transform", function () {
    this.newTypeInstance = TypeName1.get("value1"); // assumes that the cField1 is mapped to the id of this Type

    expect(this.newTypeInstance.id).toBe("value1");
    expect(this.newTypeInstance.field2).toBe("value2");
    expect(this.newTypeInstance.field3).toBe("value3");
  });

  // if necessary, test other transforms that happen on the CanonicalName type to some second Type (TypeName2)
  it("transforms Canonical Grid gas asset", function () {
    this.newAsset = TypeName2.get("value5");

    expect(this.newAsset.id).toBe("value5"); // assumes the id of this type is supposed to be value5, mapped from cField2.
    expect(this.newAsset.field4).toBe("value6");
  });


  // we need to explicitly remove the types that were created, since they were created through the process() method,
  // as opposed to TestApi.createEntity(), which would be tracked by the context.
  afterAll(function () {
    TypeName1.remove("value1");
    TypeName2.remove("value2");
    TypeName1.remove("value4");
    TypeName2.remove("value5");
    TestApi.teardown(this.ctx);
    expect(this.ctx.numObjects()).toEqual(0);
  });
});

#2

One thing to note is that we want to use “this” when creating scoped variables in describe blocks. So instead of defining the variable you would instead write the following:

  it("setup context", function () {
    this.ctx = TestApi.createContext(filename);
  });

Here is a good article about using this in jasmine tests and why:


#3

In order to use this.ctx in multiple it blocks, you’ll want to instantiate it in a beforeAll or beforeEach:

describe('my tests', function () {
  beforeAll(function () {
    this.ctx = TestApi.createContext(filename);
  });

  it('does something', function () {
    // Use `this.ctx`
  });
});