I started using ng-mocks a couple weeks ago because I thought it was designed with this case in mind but for the life of me I can't figure out how to implement it.
In short, can the value of mock providers be changed in nested describes/tests after MockBuilder/MockRender have been defined?
In my application I often have components that rely on Services that provide different data depending on the context. In cases where this is static this is simple enough to test. I'll use ActivatedRoute here as an example since it's one that's giving me grief:
const mockActivatedRoute = { snapshot: { params: { id: 1 } };
describe('MyComponent', () => {
MockInstance.scope('all');
beforeEach(() => {
return MockBuilder(MyComponent, MyModule)
.provide({ provide: ActivatedRoute, useValue: mockActivatedRoute })
});
beforeEach(() => {
fixture = MockRender(MyComponent);
component = fixture.point.componentInstance;
});
// Imagine the component has a routeId provided by the ActivatedRoute
it('should have an id of 1', () => { expect(component.routeId).toEqual(1); });
});
So far so good.
But after that test I want to run another suite that modifies the service; say the id
is now going to be 2. I assumed this was the role of MockInstance
: being able to change the provided services and such on the fly for a given test.
So to continue my example, now I'll add a nested describe
within the first after my first test:
describe('MyComponent', () => {
...
describe('when it inits with a different id', () => {
MockInstance.scope();
beforeEach(MockInstance(mockActivatedRoute, () => {
snapshot: { params: { id: 2 } }
}));
it('should have an id of 2', () => { expect(component.routeId).toEqual(2); });
});
});
This test will fail, as the new mock value was never implemented and the routeId
remained unchanged.
I realize this is a poor example. I've re-written these tests so many different ways using MockInstance.remember
or trying to init the service instance itself but haven't had any success. From what I can tell, it doesn't seem like MockBuilder and MockInstance are meant to be used together and there's no examples of such on the ng-mocks site. It seems the only way to build tests for cases like this is to build separate describes
each with their own MockBuilder and MockRender.
Or is my best option to just make routeId
public and manipulate it directly?