/*
 * Copyright (c) 2017 Mockito contributors
 * This program is made available under the terms of the MIT License.
 */
package org.mockitousage.junitrule;

import static org.mockito.Mockito.when;

import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoTestRule;
import org.mockito.quality.Strictness;
import org.mockitousage.IMethods;
import org.mockitoutil.JUnitResultAssert;

public class MutableStrictJUnitTestRuleTest {

    JUnitCore runner = new JUnitCore();

    @Test
    public void rule_can_be_changed_to_strict() throws Throwable {
        // when
        Result result = runner.run(LenientByDefault.class);

        // then
        JUnitResultAssert.assertThat(result).succeeds(1).fails(1, RuntimeException.class);
    }

    @Test
    public void rule_can_be_changed_to_lenient() throws Throwable {
        // when
        Result result = runner.run(StrictByDefault.class);

        // then
        JUnitResultAssert.assertThat(result).succeeds(1).fails(1, RuntimeException.class);
    }

    public static class LenientByDefault {
        @Rule
        public MockitoTestRule mockito = MockitoJUnit.testRule(this).strictness(Strictness.LENIENT);

        @Mock IMethods mock;

        @Test
        public void unused_stub() throws Throwable {
            when(mock.simpleMethod()).thenReturn("1");
        }

        @Test
        public void unused_stub_with_strictness() throws Throwable {
            // making Mockito strict only for this test method
            mockito.strictness(Strictness.STRICT_STUBS);

            when(mock.simpleMethod()).thenReturn("1");
        }
    }

    public static class StrictByDefault {
        @Rule
        public MockitoTestRule mockito =
                MockitoJUnit.testRule(this).strictness(Strictness.STRICT_STUBS);

        @Mock IMethods mock;

        @Test
        public void unused_stub() throws Throwable {
            when(mock.simpleMethod()).thenReturn("1");
        }

        @Test
        public void unused_stub_with_lenient() throws Throwable {
            // making Mockito lenient only for this test method
            mockito.strictness(Strictness.LENIENT);

            when(mock.simpleMethod()).thenReturn("1");
        }
    }
}
