Before: runtime autoload/ale/linter.vim runtime autoload/ale/lsp.vim runtime autoload/ale/lsp_linter.vim let g:address = 'ccls_address' let g:callback_result = 0 let g:conn_id = -1 let g:executable = 'ccls' let g:linter_name = 'ccls' let g:magic_number = 42 let g:message = -1 let g:message_id = 1 let g:method = '$ccls/call' let g:parameters = {} let g:project = '/project/root' let g:return_value = -1 let g:linter_list = [{ \ 'output_stream': 'stdout', \ 'lint_file': 0, \ 'language': 'cpp', \ 'name': g:linter_name, \ 'project_root': {b -> g:project}, \ 'aliases': [], \ 'language_callback': {b -> 'cpp'}, \ 'read_buffer': 1, \ 'command': '%e' \ }] " Encode dictionary to jsonrpc function! Encode(obj) abort let l:body = json_encode(a:obj) return 'Content-Length: ' . strlen(l:body) . "\r\n\r\n" . l:body endfunction " Register the server with given executable or address function! InitServer(executable_or_address) abort let g:conn_id = ale#lsp#Register(a:executable_or_address, g:project, {}) call ale#lsp#HandleMessage(g:conn_id, Encode({'method': 'initialize'})) endfunction " Dummy callback function! Callback(response) abort let g:callback_result = a:response.result.value endfunction " Replace the GetAll function to mock an LSP linter function! ale#linter#GetAll(filetype) abort return g:linter_list endfunction " Replace the Send function to mock an LSP linter function! ale#lsp#Send(conn_id, message) abort let g:message = a:message return g:message_id endfunction " Code for a test case function! TestCase() abort " Test sending a custom request let g:return_value = ale#lsp_linter#SendRequest(bufnr('%'), g:linter_name, g:method, g:parameters, function('Callback')) AssertEqual \ 0, \ g:return_value AssertEqual \ [0, g:method, g:parameters], \ g:message " Mock an incoming response to the request call ale#lsp#HandleMessage(g:conn_id, Encode({'id': g:message_id, 'jsonrpc': '2.0', 'result': {'value': g:magic_number}})) AssertEqual \ g:magic_number, \ g:callback_result endfunction After: if g:conn_id isnot v:null call ale#lsp#RemoveConnectionWithID(g:conn_id) endif unlet! g:callback_result unlet! g:conn_id unlet! g:executable unlet! g:linter_name unlet! g:magic_number unlet! g:message unlet! g:message_id unlet! g:method unlet! g:parameters unlet! g:project unlet! g:return_value delfunction Encode delfunction InitServer delfunction Callback delfunction TestCase runtime autoload/ale/linter.vim runtime autoload/ale/lsp.vim runtime autoload/ale/lsp_linter.vim Given cpp(Empty cpp file): Execute(Test custom request to server identified by executable): call InitServer(g:executable) let g:linter_list[0].executable = {b -> g:executable} let g:linter_list[0].lsp = 'stdio' call TestCase() Given cpp(Empty cpp file): Execute(Test custom request to server identified by address): call InitServer(g:address) let g:linter_list[0].address = {b -> g:address} let g:linter_list[0].lsp = 'socket' call TestCase()