Sure, this also makes sense when it is about math. But what I write mostly is about managing files on the disk, querying databases, processing text and XML and also some web frontend. Occasionally even communicating via a COM port. And when I need math I do it with NumPy. These tasks seem rather easy to implement and rather hard to test.
Sometimes mocking, even to check error paths, isn't a lot of work. It depends.
A lot of times designing your interfaces to support mock objects more easily improves them in other ways; if you pass in a file object instead of a filename, for example, not only does it become easier to pass in a mock object that raises an error, but it also becomes easier to pass in a GzipFile object or an HTTPResponse object, and presto, your function now handles compressed data and data stored on a web server.
with patch.object(requests, "get") as get_mock:
with nose.tools.assert_raises(socket.error):
get_mock.side_effect = socket.error
inject_exception.call_api("http://example.com")
If your functions have lots of hidden dependencies and side-effects, it’s hard to test.
If you split concerns properly and keep your glue/IO code separated from the decision-making/business-rules/logic, mocking is quite trivial, and there are advantages other than just testability.