I really am focusing on not writing brittle tests but that still test what need to be tested.
OK, if that's your goal (and it is a good one...)
One of the things that makes tests brittle is that the test becomes coupled to implementation details. Classes are like module, in that part of the motivation for creating a new class is that we've made some decision about how the solution should be implemented, and we want to limit the amount of code that knows the decision that we made. See On the criteria to be used in decomposing systems into modules (Parnas, 1982).
In particular, coupling your test to what a command should be doing is, from this perspective, risky. Instead, look for the query that you can invoke to confirm that the command did the expected thing.
Now, you are absolutely right that somewhere there is a bit of code that, given inputs x,y,z is supposed to produce a particular http request. And you will want to write a test for that code (easy - it's a query). But writing a test to confirm that A
calls this function? Yikes.
A talk that may help for your specific example is Gary Bernhardt's Boundaries. Part of the point is to keep the boundary thin; if the code isn't doing anything surprising, then it is easy to write it in a way that is too simple to hide a mistake. When we need to write tests of complicated code that talk to the boundary, we can easily replace a real boundary with test doubles (think ports and adapters).
There are, of course, some strategies for testing interactions across a process boundary. Contract testing, using tools like Pact, is one possibility. My experience has been that these strategies are more expensive, and so you want to limit them to the thin end of the testing pyramid.
Note: HTTP Patch is not safe, which is another way of saying that it is a "command". So in Sandi's grid, it falls into the expect to send bucket, with the big letter warnings about the implications of API drift.
HTTP "commands" are a little bit confusing, because they return messages, and Sandi says that commands are return nothing? And that's true, in an environment where the CQS pattern makes sense, and you have strong message delivery guarantees. But the network is not reliable, and you need some sort of acknowledgement to know that the command message got through.
So you might end up with two different sorts of tests - one where the test double for the http client is a mock, and you "expect" the correct http request to be sent, and then another sort where the test double of the http client is a "stub" that returns some fixed response to the test subject.
Both of these sorts of tests depend on the test doubles being a faithful representation of the api contract between the client and server, so you'll want to be careful there -- in particular, being willing to discard the tests and start over if somebody introduces a backwards incompatible change to that API.