Home > database >  Test the call to method into a subscribe on Jamine (Isolated Test)
Test the call to method into a subscribe on Jamine (Isolated Test)

Time:06-17

I try to test a call to method inside on a subscriber, but I can't. Always that I call to method that has a subscribe, console send to me the error "Error: Expected spy saveMug to have been called". Also fail with reContent method.

My test should be isolated, so I can´t use fixture or testbed.

This is my component code

@Component({
  selector: "app-mug",
  templateUrl: "./mug.component.html",
  styleUrls: ["./mug.component.scss"],
})
export class MugComponent implements OnInit
{

  public mug: Mug= new Mug();

  constructor(
    public constants: Constants,
    public mugService: mugService,
    private messageService: MessageService,
    public route: ActivatedRoute,
    public router: Router,
  ) {
    super(constants, route);
  }

  ngOnInit() {}

  public saveMug(previous?: boolean): void {
    const sub = this.mugService.saveMug(this.mug).subscribe((mug) => {
      if (previous === undefined || previous === false) {
        this.messageService.showMessage(
          this.constants.MUG,
          [this.constants.MUG_OK]
        );
      } else {
        this.messageService.showMessage(
          this.constants.MUG,
          [this.constants.NO_MUG]
        );
      }
      this.mug= new Mug(mug.dates);
    });
    this.subscriptions.add(sub);
  }
}

This is my Spec.ts code

describe("MugComponent", () => {
  let component;
  const constants: Constants = new Constants();
  let messageService= jasmine.createSpyObj("messageService", ["showMessage"]);
  let route;
  let router: Router;

  beforeEach(() => {
    component = new MugComponent(
      constants,
      messageService,
      route,
      router
    );
    component.mug= new Mug();
  });

  it("should call to showMessage", () => {
    spyOn(component, "showMessage");
    component.saveMug(true);
    expect(component.showMessage).toHaveBeenCalled();
  });
});

This is the Error

Error: Expected spy showMessage to have been called. at

Thanks.

CodePudding user response:

What is mugService? How do you have access to it without injecting it in the constructor?

That being said, I think you may need to use fakeAsync/tick to make the subscription happen before your assertion.

In the component, I am going to assume there is a MugService now.

constructor(
    public constants: Constants,
    private messageService: MessageService,
    private mugService: MugService,
    public route: ActivatedRoute,
    public router: Router,
  ) {
    super(constants, route);
  }
let component;
  const constants: Constants = new Constants();
  let messageService= jasmine.createSpyObj("messageService", ["showMessage"]);
  // !! create a spy
  let mugService = jasmine.createSpyObj<MugService>("MugService", ['saveMug']);
  let route;
  let router: Router;

  beforeEach(() => {
    component = new MugComponent(
      constants,
      messageService,
      // !! give spy object to component
      mugService,
      route,
      router
    );
    component.mug= new Mug();
  });
  
// !! wrap in fakeAsync
  it("should call to showMessage", fakeAsync(() => {
    // !! I don't think component.showMessage exists, messageService.showMessge does and it is already spied on
    // !! make mugService.saveMug and return an observable
    mugService.saveMug.and.returnValue(of({})); // you can mock what it returns however you wish
    component.saveMug(true);
    // !! wait for the subscription to complete
    tick();
    expect(messageService.showMessage).toHaveBeenCalled();
  });
}));

CodePudding user response:

Well, I would suggest to let the mocked messageService's saveMenu method return a value like of(new Mug()).

I assume, the test case should validate, whether the messageService got called correctly after the component's saveMug method was executed. This could be accomplished by doing something similar like:

describe("MugComponent", () => {
  let component: MugComponent;
  const constants: Constants = new Constants();
  let route;
  let router: Router;

  let messageService= jasmine.createSpyObj("messageService", ["showMessage", "saveMenu"]);
  messageService.saveMenu.and.returnValue(of(new Mug()));

  beforeEach(() => {
    component = new MugComponent(
      constants,
      messageService,
      route,
      router
    );
    component.mug = new Mug();
  });

  it("should call to showMessage", () => {
    component.saveMug(true);
    expect(messageService.showMessage).toHaveBeenCalled();
  });
});
  • Related