It seems that the main question you are asking is “how do I write test code”?
Being a fan of object-oriented programming, I know that I am biased, but in my experience it is much easier to check code written in OO style. The reason for this is that unit tests are designed to test small, isolated components of the system, and well-designed object-oriented code (mostly) provides this.
I agree that functions are often related to the context in which they are located, which makes testing them difficult. I don’t have much experience working with functional programming, but I know that this context is often passed in some kind of variable, which makes it difficult to separate the problems of functions.
With OO programming, I successfully tested objects that wrap HTTP requests, database queries, etc., making fun of an object that executes an actual network request to return a known dataset. You then verify that your wrapper is processing this data correctly. You can also check for crashes and unexpected data. Another way to do this is to configure the local server, which you use instead of the usual endpoint, but this gives your test suite an external dependency, which should be avoided when possible.
When testing HTML, many people don’t do this at all because of the very variable nature of the view layer. However, there are some things that really deserve to be tested, but never a complete line of HTML - as you discover, just a tiny change will mean that the whole test breaks. What do you really test in this case that the two lines in separate parts of your code base are the same?
The best thing is to load an HTML string from your function / object into the HTML parser library, and you can usually use Xpath or CSS selectors to check tags with specific classes, identifiers, or other attributes and check the number of elements matching certain requirements. Rspec has a built-in method ( have_tag() ), like many testing libraries.
Something else you might want to pay attention to is integration testing (e.g. Capybara, Selenium). This will load your web application using the JavaScript engine, so you can check the HTML elements as well as the JavaScript events.
Generally mocking / sealing, you usually only want to do this with objects that depend on the object you are testing. Otherwise, you can pretty much manipulate everything to claim it is true!
As for resources for testing, I would recommend looking at development test books, even if you do not plan to practice TDD. The main reason is that they first give you a head for testing. here are a few: