I assume when you mention the final class you mean the CareMessageSubject<CareChangeVO> type?
That's really not one of your problems here since the fact that it's final only means you can't reassign another instance to the reference within the scope of the reference, i.e. the method. The key to being able to test a method or any "unit" of code is to gain control of the program state, and in your case you have one particular nasty to tackle.
The method depends on a variable called careSubjectValidatorProvider that appears to be a field belonging to the class (that you don't show). Are you able to inject an instance of that class from your test case? If so then you've no problem.
The other one that may be a problem is the static call to CareMessageSubjectUtils.createSubject. If that static method is a pure function, meaning its output is completely dependent on its input, then you can include that functionality in your test and not worry about it. But if that static method depends on some other state then you're in trouble.
Questions to answer:
1. Can you inject your own careSubjectValidatorProvider?
2. Is CareMessageSubjectUtils.createSubject deterministic? Or does it rely on external state?
The class CareMessageSubject<CareChangeVO> is not final. but it has some fields that are final.
1. Yes it is injected using this line:
2. The class "CareMessageSubjectUtils" is final with static methods:
I think here I need to test CareSubjectValidator<CareChangeVO>.validate is called on subject. and that CareSubjectValidator<CareChangeProductVO>.validate is called if there are any products. and that any validationMessages are returned.
But I am not sure how to perform this test yet.
Assuming that the injection of the CareSubjectValidatorProvider work ok then it looks to me like you have everything you need to test this unit.
The basic format of any test is Arrange, Act, Assert.
Arrange: Set up the prerequisite state for your test. In your case you have 3 pieces of state to handle, the method arguments CareMessageSubject<CareChangeVO> and Date, and the class member CareSubjectValidatorProvider.
Act: Call the method.
Assert: Check the returned ValidationMessages object is in the correct state.
In your case the complexity is in the Arrange part of the process, but at the end of it you'll have a much better understanding of how the code behaves and how the inputs influence the outputs.
On a second look, you don't need to instantiate a CareSubjectValidator yourself because that's the job of the CareSubjectValidatorProvider. You do need to instantiate a CareSubjectValidatorProvider and inject that into your class somehow.