Currently, org.springframework.boot.test.mock.mockito.MockBean has Answers as answer type. This limits the possible options here to what explicitly is defined in org.mockito.Answers, and only that. Providing a custom default answer is impossible, because that enum is obviously final. However, Answers implements Answer<Object> - so, it should be possible to change MockBean to just accept Answer<Object> without having to break backwards compatibility in a significant way, and that would only require slight tweaking of the implementation at https://github.com/spring-projects/spring-boot/blob/main/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/DefinitionsParser.java#L86 & MockDefinition.java , with exactly zero logic changes underneath, since Mockito actually accepts Answer as defaultAnswer param anyway.

I can do a PR for this BTW if that's OK/needed, seems trivial enough.

Comment From: wilkinsona

Thanks for the suggestion but Answer<Object> isn't a valid type for an annotation attribute. They have to be a primitive, a String, a Class, an annotation, or an enum.

Comment From: FyiurAmron

@wilkinsona I get your point & I completely understand, because what you said is true in the strict sense, but technically it's not a real limitation here. You can have an enum with a custom value that's mutable, and use that value for the job. See https://gist.github.com/FyiurAmron/d903b6f4e6dca0d3132e6e8f7ade3c2a for what I had in mind. You then need to configure the custom behaviour on-demand before using the mock. I'm not saying this is a particularly good idea, and I understand your concerns here. Still, mocks basically work like that anyway, they are low-level hacks and VM tricks one way or another. This way works and is doable. The fact that VM explicitly expects "constant" values IMVHO has no real meaning when those values have no enforced immutability contract (which is the case of Java's enum; the other cases are immutable enough I'd say). Not that I disagree with you, come to think of it I shouldn't propose it, it's ugly, and yeah, that wouldn't be "real" backwards-compatibility, since the enums would come from different packages anyway :/

However, do you know of any reasonably straightforward way to change the default answer for a MockBean then? https://github.com/spring-projects/spring-boot/blob/main/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockDefinition.java#L154 & L158 seem like the limiting factor here to do any kind of injection of custom default answer.

Comment From: wilkinsona

Unfortunately, the limitations of Java's annotations are such that there's no easy way for us to allow a custom Answer to be provided with @MockBean. For example, a Class<? extends Answer<?>> attribute would not help as Class attributes may not have a default value of null. A separate @Answer annotation could overcome this but it wouldn't allow many of Mockito's additional answers to be used as they're in its internal package and only intended for exposure through the static method on AdditionalAnswers. Such method referencing is not possible from an annotation attribute.

If you need this level of control over your mocks, @MockBean may not be the best choice. A @Bean method that returns a mock created using Mockito's API directly is a better option here.