You have various options depending on the tools you are willing to use and the depth your tests should have.
Partial Mocking with plain Java
Create a class (MockElephant) that extends from elephant, overwrite makeNoise
so it counts the number of invocations. Use that class in your test to check that makeNoise
was called the correct number of times
Partial Mocking with a Framework
You basically do the same as above but instead of manually coding the MockElephant you create it using some mocking framework. Makes the test much simpler, since you need less code. And it is easier to read. But if strange things happen it makes it harder to understand what is going on. In case of Mocking frameworks I think they are worth it.
The reasons why this is called Partial Mocking is that you mock only parts of a class (a single method in this case).
The alternative is to use Normal Mocks, which in your case seems feasible (but can become tough in legacy code).
Here you would inject the Logger as a dependency. For example you could create an additional constructor which allows you to provide the Logger. In your test you would then use a mocked Logger, which again counts it's invocations, probably along with the parameter it received and check that it has the expected values.
Again you can do that with a Mocking Framework or with plain old Java.