Test behavior. Focus on that and many structural issues can be ignored.
Now sure, all testing happens against some interface, some boundary. And likely there is more than one choice of interface/boundary that still gets to the same behavior. That structural choice has some implications.
Would you write tests only for its subclasses or would you do a "mock class" just to check its behavior? If any of this, what would you?
Tests that fully isolate the abstract class, mocking out any dependencies or children have a lot of pros. They leave you with little code under the test to read. That makes them easy to debug and typically fast since they don't do much. But they have a lot of problems. Chiefly they know a lot of implementation details. They have to to mock all those collaborators. Which is really bad since under this style you'll also need a lot of tests. Test like this and making any implementation changes, that aren't concealed / abstracted by the one class, become impossible without deleting or redesigning tests. This testing style can actually drive people to work more procedurally since extracting a new class forces the creation of so many more tests.
Folwer called these Solitary Tests. He contrasted them with what he called Sociable Tests. Tests that stepped back from the class boundary and let many classes work together under the test (as a unit). These kinds of tests allow more to be abstracted away from them and so more implementation is hidden and available to be refactored without breaking the test.
That comes with a cost as well. More code falls under the test. Thus it can take longer to find a bug since there is more code to read. Tests can take longer to run and so they are run less frequently.
Your question boils down to the same choice. You've simply focused on the case where this is happening to an inheritance structure. You can still fully isolate. But should you?
Fowler favored the Social Tests but acknowledged you can use both. My problem with that is when you mix the two kinds of tests in the same bucket. If you're going to do both I say keep these tests segregated. The "fully isolated/solitary/developer" tests are fast but more likely to need deleting as things change. They can do a lot of damage just by making people reluctant to get rid of them. You can help with that by not mixing them with the slower longer lasting Social ones.
As for which you should choose in this particular case, that fully depends on your needs. Do you, right now, need some focused help developing the behavior inside this abstract class without being distracted by the children? Or do you need to ensure you're getting the behavior you need even when children are involved?
Like I said, you can do both. Just please don't mix these testing styles together in the same place. It gets confusing.
IPresenter
) that resides in the Use Cases layer and is owned by (or specified by, required by) the Interactor. In your code, the output port is implicit, as it's not represented by a type (you specified the parameter asany
). 1/2{ showSuccess, showError }
. Note that this is exactly what's depicted in the lower-right corner in this image. It's the DI principle: the interactor needs to call the presenter - but cannot depend on it directly, instead, it relies on the fact that the instance given to it implements a certain set of methods - the interface specified in the UseCases lyr, but implemented in the Adapters lyr. 2/2any
, if you actually pass an object that doesn't have{ showSuccess, showError }
, your interactor will break - which illustrates that it does depend on an interface, it's just that this interface is not explicitly represented in code. (I'm using the word interface in the traditional sense - the public API of an object, the set of it's public methods + their semantics.)