0

I have the next controller:

@EnableWebMvc
@RequestMapping("experiences")
@RestController("experience_controller")
public class ExperienceController {

    @Autowired
    private ExperienceManager mExperienceManager;

    protected boolean mIsTest = false; //I need to replace by 'true'

    @PostMapping(value = "new")
    public ResponseEntity<ExperienceModel> add(
            @RequestBody NewExperienceModel newExperience
    ) {
        if (!mIsTest) {
            ExperienceUtils.validate(newExperience);
        }

        Experience experience = newExperience.toExperience();

        if (!mExperienceManager.add(experience)) {
            throw new InternalServerException(ServerError.INTERNAL);
        }

        return new ResponseEntity<>(new ExperienceModel(experience),
                HttpStatus.CREATED);
    }
}

And my application test class:

@TestPropertySource(properties = { "com.contedevel.virto.experience.controllers.ExperienceController.mIsTest=true" })
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class ExperienceControllerTest {

    @Autowired
    private MockMvc mMockMvc;
    private ObjectMapper mMapper;
    private NewExperienceModel mModel;
    private String mExperienceId;

    @Before
    public void setUp() {
        mMapper = new ObjectMapper();
        UUID userId = UUID.randomUUID();
        UUID gameId = UUID.randomUUID();
        UUID achievementId = UUID.randomUUID();
        float value = 50f;
        mModel = new NewExperienceModel(userId, gameId, achievementId, value);
    }

    @Test()
    public void testOrder() throws Exception {
        testPost();
    }

    private void testPost() throws Exception {
        String json = mMapper.writeValueAsString(mModel);
        final String url = "/experiences/new";

        MvcResult result = mMockMvc.perform(post(url)
                .accept(MediaType.APPLICATION_JSON)
                .contentType(MediaType.APPLICATION_JSON)
                .content(json))
                .andDo(print())
                .andExpect(status().isCreated())
                .andReturn();
        String response = result.getResponse()
                .getContentAsString();
        JSONObject obj = new JSONObject(response);
        mExperienceId = obj.getString(ExperienceKeys.ID);
    }
}

I need to set mIsTest = true in my controller... Of course, I know this code is wrong but how to make so? Or do I need to change it manually each time?

Denis Sologub
  • 7,277
  • 11
  • 56
  • 123
  • 1
    You could change `ExperienceUtils` to a bean and inject a mocked one for the test. – Dan W Jan 29 '18 at 22:16
  • @DanW, thank you! Imma noobie in Spring, honestly, but I'll try to get how to write a custom bean. – Denis Sologub Jan 29 '18 at 22:17
  • There is an immediate code-based solution to your immediate problem, but wanting to put escape-hatch code like that into a production system has a very strong smell about it. – Makoto Feb 09 '18 at 21:28

1 Answers1

1

How about use @Value ?

public class ExperienceController {
    ...
    @Value("${flag.test:false}")
    protected boolean mIsTest;
    ...
}

And test code

...
@TestPropertySource(properties = {"flag.test = true"})
public class ExperienceControllerTest {
   ...
}

The default value of mIsTest is false and you can change value of mIsTest with property flag.test (or whatever). You can change its value with properties files and active profiles.

If you want quick guide to @Value, refer here : http://www.baeldung.com/spring-value-annotation

Min Hyoung Hong
  • 1,102
  • 9
  • 13