diff --git a/public/app/core/components/Layers/LayerName.test.tsx b/public/app/core/components/Layers/LayerName.test.tsx index bd367d36174..f1fc690f37d 100644 --- a/public/app/core/components/Layers/LayerName.test.tsx +++ b/public/app/core/components/Layers/LayerName.test.tsx @@ -12,7 +12,7 @@ describe('LayerName', () => { fireEvent.change(input, { target: { value: 'new name' } }); fireEvent.blur(input); - expect((scenario.props.onChange as any).mock.calls[0][0]).toBe('new name'); + expect(jest.mocked(scenario.props.onChange).mock.calls[0][0]).toBe('new name'); }); it('Show error when empty name is specified', async () => { diff --git a/public/app/features/explore/Wrapper.test.tsx b/public/app/features/explore/Wrapper.test.tsx index b80c6081306..ad0a1c665e6 100644 --- a/public/app/features/explore/Wrapper.test.tsx +++ b/public/app/features/explore/Wrapper.test.tsx @@ -10,8 +10,6 @@ import { makeLogsQueryResponse, makeMetricsQueryResponse } from './spec/helper/q import { setupExplore, tearDown, waitForExplore } from './spec/helper/setup'; import { splitOpen } from './state/main'; -type Mock = jest.Mock; - jest.mock('app/core/core', () => { return { contextSrv: { @@ -70,7 +68,7 @@ describe('Wrapper', () => { }), }; const { datasources } = setupExplore({ urlParams }); - (datasources.loki.query as Mock).mockReturnValueOnce(makeLogsQueryResponse()); + jest.mocked(datasources.loki.query).mockReturnValueOnce(makeLogsQueryResponse()); // Make sure we render the logs panel await screen.findByText(/^Logs$/); @@ -89,7 +87,7 @@ describe('Wrapper', () => { // We called the data source query method once expect(datasources.loki.query).toBeCalledTimes(1); - expect((datasources.loki.query as Mock).mock.calls[0][0]).toMatchObject({ + expect(jest.mocked(datasources.loki.query).mock.calls[0][0]).toMatchObject({ targets: [{ expr: '{ label="value"}' }], }); }); @@ -97,11 +95,11 @@ describe('Wrapper', () => { it('handles url change and runs the new query', async () => { const urlParams = { left: JSON.stringify(['now-1h', 'now', 'loki', { expr: '{ label="value"}' }]) }; const { datasources } = setupExplore({ urlParams }); - (datasources.loki.query as Mock).mockReturnValueOnce(makeLogsQueryResponse()); + jest.mocked(datasources.loki.query).mockReturnValueOnce(makeLogsQueryResponse()); // Wait for rendering the logs await screen.findByText(/custom log line/i); - (datasources.loki.query as Mock).mockReturnValueOnce(makeLogsQueryResponse('different log')); + jest.mocked(datasources.loki.query).mockReturnValueOnce(makeLogsQueryResponse('different log')); locationService.partial({ left: JSON.stringify(['now-1h', 'now', 'loki', { expr: '{ label="different"}' }]), @@ -116,12 +114,12 @@ describe('Wrapper', () => { it('handles url change and runs the new query with different datasource', async () => { const urlParams = { left: JSON.stringify(['now-1h', 'now', 'loki', { expr: '{ label="value"}' }]) }; const { datasources } = setupExplore({ urlParams }); - (datasources.loki.query as Mock).mockReturnValueOnce(makeLogsQueryResponse()); + jest.mocked(datasources.loki.query).mockReturnValueOnce(makeLogsQueryResponse()); // Wait for rendering the logs await screen.findByText(/custom log line/i); await screen.findByText(`loki Editor input: { label="value"}`); - (datasources.elastic.query as Mock).mockReturnValueOnce(makeMetricsQueryResponse()); + jest.mocked(datasources.elastic.query).mockReturnValueOnce(makeMetricsQueryResponse()); locationService.partial({ left: JSON.stringify(['now-1h', 'now', 'elastic', { expr: 'other query' }]), @@ -136,7 +134,7 @@ describe('Wrapper', () => { it('handles changing the datasource manually', async () => { const urlParams = { left: JSON.stringify(['now-1h', 'now', 'loki', { expr: '{ label="value"}', refId: 'A' }]) }; const { datasources } = setupExplore({ urlParams }); - (datasources.loki.query as Mock).mockReturnValueOnce(makeLogsQueryResponse()); + jest.mocked(datasources.loki.query).mockReturnValueOnce(makeLogsQueryResponse()); await waitForExplore(); await changeDatasource('elastic'); @@ -178,8 +176,8 @@ describe('Wrapper', () => { }; const { datasources } = setupExplore({ urlParams }); - (datasources.loki.query as Mock).mockReturnValueOnce(makeLogsQueryResponse()); - (datasources.elastic.query as Mock).mockReturnValueOnce(makeLogsQueryResponse()); + jest.mocked(datasources.loki.query).mockReturnValueOnce(makeLogsQueryResponse()); + jest.mocked(datasources.elastic.query).mockReturnValueOnce(makeLogsQueryResponse()); // Make sure we render the logs panel await waitFor(() => { @@ -203,12 +201,12 @@ describe('Wrapper', () => { // We called the data source query method once expect(datasources.loki.query).toBeCalledTimes(1); - expect((datasources.loki.query as Mock).mock.calls[0][0]).toMatchObject({ + expect(jest.mocked(datasources.loki.query).mock.calls[0][0]).toMatchObject({ targets: [{ expr: '{ label="value"}' }], }); expect(datasources.elastic.query).toBeCalledTimes(1); - expect((datasources.elastic.query as Mock).mock.calls[0][0]).toMatchObject({ + expect(jest.mocked(datasources.elastic.query).mock.calls[0][0]).toMatchObject({ targets: [{ expr: 'error' }], }); }); @@ -233,8 +231,8 @@ describe('Wrapper', () => { left: JSON.stringify(['now-1h', 'now', 'loki', { expr: '{ label="value"}' }]), }; const { datasources } = setupExplore({ urlParams }); - (datasources.loki.query as Mock).mockReturnValue(makeLogsQueryResponse()); - (datasources.elastic.query as Mock).mockReturnValue(makeLogsQueryResponse()); + jest.mocked(datasources.loki.query).mockReturnValue(makeLogsQueryResponse()); + jest.mocked(datasources.elastic.query).mockReturnValue(makeLogsQueryResponse()); locationService.partial({ left: JSON.stringify(['now-1h', 'now', 'loki', { expr: '{ label="value"}' }]), @@ -251,8 +249,8 @@ describe('Wrapper', () => { left: JSON.stringify(['now-1h', 'now', 'loki', { expr: '{ label="value"}' }]), }; const { datasources, store } = setupExplore({ urlParams }); - (datasources.loki.query as Mock).mockReturnValue(makeLogsQueryResponse()); - (datasources.elastic.query as Mock).mockReturnValue(makeLogsQueryResponse()); + jest.mocked(datasources.loki.query).mockReturnValue(makeLogsQueryResponse()); + jest.mocked(datasources.elastic.query).mockReturnValue(makeLogsQueryResponse()); // This is mainly to wait for render so that the left pane state is initialized as that is needed for splitOpen // to work @@ -270,7 +268,7 @@ describe('Wrapper', () => { left: JSON.stringify(['now-1h', 'now', 'loki', { expr: '{ label="value"}' }]), }; const { datasources } = setupExplore({ urlParams }); - (datasources.loki.query as Mock).mockReturnValue(makeLogsQueryResponse()); + jest.mocked(datasources.loki.query).mockReturnValue(makeLogsQueryResponse()); // This is mainly to wait for render so that the left pane state is initialized as that is needed for the title // to include the datasource await screen.findByText(`loki Editor input: { label="value"}`); @@ -282,8 +280,8 @@ describe('Wrapper', () => { left: JSON.stringify(['now-1h', 'now', 'loki', { expr: '{ label="value"}' }]), }; const { datasources, store } = setupExplore({ urlParams }); - (datasources.loki.query as Mock).mockReturnValue(makeLogsQueryResponse()); - (datasources.elastic.query as Mock).mockReturnValue(makeLogsQueryResponse()); + jest.mocked(datasources.loki.query).mockReturnValue(makeLogsQueryResponse()); + jest.mocked(datasources.elastic.query).mockReturnValue(makeLogsQueryResponse()); // This is mainly to wait for render so that the left pane state is initialized as that is needed for splitOpen // to work diff --git a/public/app/features/explore/state/query.test.ts b/public/app/features/explore/state/query.test.ts index 7ca0899a377..7a8b85aa51f 100644 --- a/public/app/features/explore/state/query.test.ts +++ b/public/app/features/explore/state/query.test.ts @@ -1,5 +1,6 @@ import { EMPTY, interval, Observable, of } from 'rxjs'; import { thunkTester } from 'test/core/thunk/thunkTester'; +import { assertIsDefined } from 'test/helpers/asserts'; import { ArrayVector, @@ -37,8 +38,6 @@ import { } from './query'; import { makeExplorePaneState } from './utils'; -import Mock = jest.Mock; - const { testRange, defaultInitialState } = createDefaultInitialState(); jest.mock('app/features/dashboard/services/TimeSrv', () => ({ @@ -57,7 +56,9 @@ jest.mock('@grafana/runtime', () => ({ })); function setupQueryResponse(state: StoreState) { - (state.explore[ExploreId.left].datasourceInstance?.query as Mock).mockReturnValueOnce( + const leftDatasourceInstance = assertIsDefined(state.explore[ExploreId.left].datasourceInstance); + + jest.mocked(leftDatasourceInstance.query).mockReturnValueOnce( of({ error: { message: 'test error' }, data: [ @@ -107,7 +108,8 @@ describe('runQueries', () => { const { dispatch, getState } = configureStore({ ...(defaultInitialState as any), }); - (getState().explore[ExploreId.left].datasourceInstance?.query as Mock).mockReturnValueOnce(EMPTY); + const leftDatasourceInstance = assertIsDefined(getState().explore[ExploreId.left].datasourceInstance); + jest.mocked(leftDatasourceInstance.query).mockReturnValueOnce(EMPTY); await dispatch(runQueries(ExploreId.left)); await new Promise((resolve) => setTimeout(() => resolve(''), 500)); expect(getState().explore[ExploreId.left].queryResponse.state).toBe(LoadingState.Done); diff --git a/public/app/features/query/components/QueryEditorRowHeader.test.tsx b/public/app/features/query/components/QueryEditorRowHeader.test.tsx index 736c8bc2a95..3b3a7367867 100644 --- a/public/app/features/query/components/QueryEditorRowHeader.test.tsx +++ b/public/app/features/query/components/QueryEditorRowHeader.test.tsx @@ -32,7 +32,7 @@ describe('QueryEditorRowHeader', () => { fireEvent.change(input, { target: { value: 'new name' } }); fireEvent.blur(input); - expect((scenario.props.onChange as any).mock.calls[0][0].refId).toBe('new name'); + expect(jest.mocked(scenario.props.onChange).mock.calls[0][0].refId).toBe('new name'); }); it('Show error when other query with same name exists', async () => { diff --git a/public/app/plugins/datasource/prometheus/language_provider.test.ts b/public/app/plugins/datasource/prometheus/language_provider.test.ts index 258ebc1802f..152d05f47de 100644 --- a/public/app/plugins/datasource/prometheus/language_provider.test.ts +++ b/public/app/plugins/datasource/prometheus/language_provider.test.ts @@ -8,8 +8,6 @@ import { PrometheusDatasource } from './datasource'; import LanguageProvider from './language_provider'; import { PromQuery } from './types'; -import Mock = jest.Mock; - describe('Language completion provider', () => { const datasource: PrometheusDatasource = { metadataRequest: () => ({ data: { data: [] as any[] } }), @@ -582,6 +580,8 @@ describe('Language completion provider', () => { interpolateString: (string: string) => string, } as any as PrometheusDatasource; + const mockedMetadataRequest = jest.mocked(datasource.metadataRequest); + const instance = new LanguageProvider(datasource); const value = Plain.deserialize('{}'); const ed = new SlateEditor({ value }); @@ -594,11 +594,11 @@ describe('Language completion provider', () => { }; const promise1 = instance.provideCompletionItems(args); // one call for 2 default labels job, instance - expect((datasource.metadataRequest as Mock).mock.calls.length).toBe(2); + expect(mockedMetadataRequest.mock.calls.length).toBe(2); const promise2 = instance.provideCompletionItems(args); - expect((datasource.metadataRequest as Mock).mock.calls.length).toBe(2); + expect(mockedMetadataRequest.mock.calls.length).toBe(2); await Promise.all([promise1, promise2]); - expect((datasource.metadataRequest as Mock).mock.calls.length).toBe(2); + expect(mockedMetadataRequest.mock.calls.length).toBe(2); }); }); describe('disabled metrics lookup', () => { @@ -609,6 +609,7 @@ describe('Language completion provider', () => { getTimeRangeParams: jest.fn(() => ({ start: '0', end: '1' })), lookupsDisabled: true, } as any as PrometheusDatasource; + const mockedMetadataRequest = jest.mocked(datasource.metadataRequest); const instance = new LanguageProvider(datasource); const value = Plain.deserialize('{}'); const ed = new SlateEditor({ value }); @@ -620,11 +621,11 @@ describe('Language completion provider', () => { value: valueWithSelection, }; - expect((datasource.metadataRequest as Mock).mock.calls.length).toBe(0); + expect(mockedMetadataRequest.mock.calls.length).toBe(0); await instance.start(); - expect((datasource.metadataRequest as Mock).mock.calls.length).toBe(0); + expect(mockedMetadataRequest.mock.calls.length).toBe(0); await instance.provideCompletionItems(args); - expect((datasource.metadataRequest as Mock).mock.calls.length).toBe(0); + expect(mockedMetadataRequest.mock.calls.length).toBe(0); expect(console.warn).toHaveBeenCalledWith('Server did not return any values for selector = {}'); }); it('issues metadata requests when lookup is not disabled', async () => { @@ -634,11 +635,12 @@ describe('Language completion provider', () => { lookupsDisabled: false, interpolateString: (string: string) => string, } as any as PrometheusDatasource; + const mockedMetadataRequest = jest.mocked(datasource.metadataRequest); const instance = new LanguageProvider(datasource); - expect((datasource.metadataRequest as Mock).mock.calls.length).toBe(0); + expect(mockedMetadataRequest.mock.calls.length).toBe(0); await instance.start(); - expect((datasource.metadataRequest as Mock).mock.calls.length).toBeGreaterThan(0); + expect(mockedMetadataRequest.mock.calls.length).toBeGreaterThan(0); }); }); diff --git a/public/test/helpers/asserts.ts b/public/test/helpers/asserts.ts index 994741e0137..7be6a3860b7 100644 --- a/public/test/helpers/asserts.ts +++ b/public/test/helpers/asserts.ts @@ -8,3 +8,11 @@ export function assertInstanceOf(value: T | null | undefined): T { + if (value == null) { + throw new Error(`Expected value to not be null but got ${typeof value}`); + } + + return value; +}