OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

Class field is not being set

  • Thread starter Thread starter alaboudi
  • Start date Start date
A

alaboudi

Guest
I'm building my own CQRS library and I seem to have an issue understanding why a certain field is not being correctly set. More specifically, the issue seems to be present in classes that extend my AggregateRoot abstract class. See the following Typescript code:

Code:
import Entity from "./entity";
import Event from "./event";

export enum AggregateRootConstructionTypes {
    Create,
    Load
}

type CreateConstructorParams = {
    type: AggregateRootConstructionTypes.Create,
    createParams?: any;
}

type LoadConstructorParams = {
    type: AggregateRootConstructionTypes.Load,
    history: Event[]
}

type AggregateRootConstructorParams = CreateConstructorParams | LoadConstructorParams;

abstract class AggregateRoot extends Entity {
    private _events: Event[] = [];
    private _version: number = -1;

    get domainEvents(): Event[] {
        return this._events;
    }

    get version(): number {
        return this._version;
    }

    addDomainEvent(event: Event): void {
        this._events.push(event);
    }

    clearEvents(): void {
        this._events.splice(0, this._events.length);
    }

    protected apply(event: Event): void {
        this._events.push(event);
        this._version++;
        this.when(event);
    }

    protected abstract when(event: Event): void;
    protected abstract create(input: any): void;

    protected loadFromHistory(history: Event[]): void {
        history.forEach((event) => {
            this.when(event);
            this._version++;
        });
    }

    constructor(params: AggregateRootConstructorParams) {
        super();
        if (params.type === AggregateRootConstructionTypes.Create) {
            this.create(params.createParams);
        } else {
            this.loadFromHistory(params.history);
        }
    }
}

export default AggregateRoot;

The issue is in the following test

Code:
import AggregateRoot, {AggregateRootConstructionTypes} from "./aggregate-root";
import Event from "./event";

describe('AggregateRoot', () => {
   class CreatedEvent extends Event {}

    class ExtendedAggregateRoot extends AggregateRoot {
       create() {
           const createdEvent = new CreatedEvent();
           this.apply(createdEvent);
       }

       someState: number = 0;

       private handleCreatedEvent() {
           this.someState = 1;
       }

       protected when(event: Event) {
           if (event instanceof CreatedEvent) {
               this.handleCreatedEvent();
           }
       }
   }

    describe('when applying an event', () => {
       it('should update the version, register an event, and trigger the handler in the when() function', () => {
           const EAR = new ExtendedAggregateRoot({ type: AggregateRootConstructionTypes.Create });
           expect(EAR.version).toEqual(0);
           expect(EAR.domainEvents).toHaveLength(1);
           expect(EAR.someState).toEqual(1); // ----------> this line fails
       });
    });
});

the last expect statement fails. Please help me understand why. I tried logging along the way and it oddly states that some someState seems to be set to 1. but when asserting the value, it seems like its still set to 0. This makes me believe that I potentially may have lost execution context with how I have written my code but I can't seem to identify where. Any help is appreciated.

<p>I'm building my own CQRS library and I seem to have an issue understanding why a certain field is not being correctly set. More specifically, the issue seems to be present in classes that extend my AggregateRoot abstract class. See the following Typescript code:</p>
<pre class="lang-js prettyprint-override"><code>import Entity from "./entity";
import Event from "./event";

export enum AggregateRootConstructionTypes {
Create,
Load
}

type CreateConstructorParams = {
type: AggregateRootConstructionTypes.Create,
createParams?: any;
}

type LoadConstructorParams = {
type: AggregateRootConstructionTypes.Load,
history: Event[]
}

type AggregateRootConstructorParams = CreateConstructorParams | LoadConstructorParams;

abstract class AggregateRoot extends Entity {
private _events: Event[] = [];
private _version: number = -1;

get domainEvents(): Event[] {
return this._events;
}

get version(): number {
return this._version;
}

addDomainEvent(event: Event): void {
this._events.push(event);
}

clearEvents(): void {
this._events.splice(0, this._events.length);
}

protected apply(event: Event): void {
this._events.push(event);
this._version++;
this.when(event);
}

protected abstract when(event: Event): void;
protected abstract create(input: any): void;

protected loadFromHistory(history: Event[]): void {
history.forEach((event) => {
this.when(event);
this._version++;
});
}

constructor(params: AggregateRootConstructorParams) {
super();
if (params.type === AggregateRootConstructionTypes.Create) {
this.create(params.createParams);
} else {
this.loadFromHistory(params.history);
}
}
}

export default AggregateRoot;
</code></pre>
<p>The issue is in the following test</p>
<pre class="lang-js prettyprint-override"><code>import AggregateRoot, {AggregateRootConstructionTypes} from "./aggregate-root";
import Event from "./event";

describe('AggregateRoot', () => {
class CreatedEvent extends Event {}

class ExtendedAggregateRoot extends AggregateRoot {
create() {
const createdEvent = new CreatedEvent();
this.apply(createdEvent);
}

someState: number = 0;

private handleCreatedEvent() {
this.someState = 1;
}

protected when(event: Event) {
if (event instanceof CreatedEvent) {
this.handleCreatedEvent();
}
}
}

describe('when applying an event', () => {
it('should update the version, register an event, and trigger the handler in the when() function', () => {
const EAR = new ExtendedAggregateRoot({ type: AggregateRootConstructionTypes.Create });
expect(EAR.version).toEqual(0);
expect(EAR.domainEvents).toHaveLength(1);
expect(EAR.someState).toEqual(1); // ----------> this line fails
});
});
});
</code></pre>
<p>the last expect statement fails. Please help me understand why. I tried logging along the way and it oddly states that some <code>someState</code> seems to be set to 1. but when asserting the value, it seems like its still set to 0. This makes me believe that I potentially may have lost execution context with how I have written my code but I can't seem to identify where. Any help is appreciated.</p>
 
Top