3

I'm using Mockito for unit testing, and as such, it looks like i'm able to inject certain objects using the @InjectMocks and @Mock annotations. I'm assuming i can do this for Object type Booleans

However, i can't seem to get this to work for primitive booleans. How do i do this? or what frameworks allow this? (i'm actually on an Android project)

for example:

class MethCook {
    private Laboratory mLab; // i can inject this
    private Assistant mJessePinkman; // this is injectable too
    private boolean mCanCookPureCrystal; // how do i access/inject this?

    private void cookBlueMeth() { ... }

    private void onTraumatized() {
        mCanCookPureCrystal = false;
        startMoppingAround();
        beDepressed();
        neverWantToCookAgain();
    }
}

note: elegance meaning brevity and conciseness, as in... i would prefer not to use @VisibleForTesting on top of getter/setters to access this boolean; as that would expose state mutability to the outside world?

David T.
  • 22,301
  • 23
  • 71
  • 123

2 Answers2

2

If there's Inversion of Control, (@Autowired/@Value/@Resource), reflection is easy enough.

    @Before 
    public void init() {
        Field f = myMethCooking.getClass().getDeclaredField("mCanCookPureCrystal");
        f.setAccessible(true);
        f.set(myMethCooking, false);
    }

java-set-field-value-with-reflection!

Community
  • 1
  • 1
devaaron
  • 101
  • 9
  • The rule of thumb is not to use reflection until there's no other way and here are much simpler and nicer ways - e.g. package private setter ;) – chipiik Feb 07 '17 at 15:28
1

Mockito is a mocking framework, not an injection framework. The @Mock annotation does not support mocking things the developer doesn't own, like boolean.class.

Try setting the boolean in JUnit's @Before annotation, something like:

@Before public void inject_mCanCookPureCrystal() {
    myMethCooking.setMCanCookPureCrystal(false);
}

Here is an issue in Mockito's enhancement request database that talks about extending annotations, possibly in a way that can be used with primitives: Mockito Issue 290.

If there is no setter for the value, then you'll want to execute a method that sets it as needed beforehand. Many testers will argue that if something can't be directly set externally, it's not part of the class's public contract and should not be set by injection, reflection, annotations or anything else, anyway. (See https://stackoverflow.com/a/2811171/325452 .)

Community
  • 1
  • 1
ingyhere
  • 11,818
  • 3
  • 38
  • 52