I understand why you say this but you can say the same thing about the controller tests in a JSON API if they are only consumed by your own UI code. Your tests send some data, get some data back, make some assertions. None of that proves it will meet the expectation of the UI code, yet still these tests are very useful and provide a lot of value that is unquestioned. That data you prepare for a request? Its a mock.
When we first started testing our front-end SPA code, we struggled with this quite a lot. We use Jest which has nice mocking but still creating the mocks is tedious and very often we spend far more time preparing data mocks to get our test working than we spent coding the new functionality under test. We so far do not see nearly so much value in these tests. Where we can write unit tests (a discrete piece of logic unconnected to UI/Store/API) the value is much easier to see. Still, the component tests run very fast and so its economical to test edge cases and to add coverage for bugs once the component itself is stood up.
Actually I find it much much faster to write E2E tests (we use Cypress, which is awesome and very fast to iterate on). The Cypress tests use the Phoenix’s Plug SQL Sandbox feature so we can use
ex_machina to prepare data for each test and roll it back afterward just like a controller test (we have a fixture controller the test code can invoke to create a list of mocks). When we test this way its very easy to see the value in what it is doing, but unfortunately it is slow so we only use it to test a basic critical happy-path for each module of app (and not all the ancillary features).