Mockito ClassCastException with casting field - unit-testing

I'm trying to write unit test for the following code:
public DesiredCapabilities findCapability(Platforms platform, Types type, String browser, double platformVersion) throws Exception{
Criteria criteria = getSession().createCriteria(BrowserCapabilities.class)
.add(Restrictions.eq("status", ICommonConstants.DB_STATUS_ACTIVE))
.add(Restrictions.eq("platformName", platform.getValue()))
.add(Restrictions.eq("browserName", browser))
.add(Restrictions.eq("platformVersion", platformVersion))
.addOrder(Order.desc("browserVersion"))
.setMaxResults(1);
Object res = criteria.uniqueResult();
if(res!=null)
return this.prepareBrowserCapability((BrowserCapabilities)res);
return null;
}
The mock code is:
private BrowserCapabilityDAO mockBrowserCapability;
private Session mockSession;
private Criteria mockCriteria;
private Criterion mockCriterion;
#Before
public void init() {
mockBrowserCapability = Mockito.spy(new BrowserCapabilityDAO());
mockSession = Mockito.mock(Session.class, Mockito.RETURNS_DEEP_STUBS);
mockCriteria = Mockito.mock(Criteria.class, Mockito.RETURNS_DEEP_STUBS);
mockCriterion = Mockito.mock(Criterion.class, Mockito.RETURNS_DEEP_STUBS);
}
#Test
public void testFindCapability() throws Exception {
DesiredCapabilities desiredCapability = new DesiredCapabilities();
BrowserCapabilities mockBrowserCapabilities = getMockBrowserCapabilities();
//Stub
Mockito.doReturn(mockSession).when(mockBrowserCapability).getSession();
Mockito.when(mockSession.createCriteria(Mockito.eq(BrowserCapabilities.class))).thenReturn(mockCriteria);
Mockito.doReturn(mockCriteria).when(mockCriteria).add(mockCriterion);
Mockito.when(mockCriteria.addOrder(Mockito.any(Order.class))).thenReturn(mockCriteria);
Mockito.when(mockCriteria.setMaxResults(Mockito.anyInt())).thenReturn(mockCriteria);
Mockito.when(mockCriteria.uniqueResult()).thenReturn((Object)mockBrowserCapabilities);
//Mockito.doReturn(desiredCapability).when(mockBrowserCapability).prepareBrowserCapability(mockBrowserCapabilities);
mockBrowserCapability.findCapability(Platforms.WINDOWS, Types.COMPUTER, "FF", 10.0);
}
private BrowserCapabilities getMockBrowserCapabilities() {
BrowserCapabilities mockBrowserCapabilities = new BrowserCapabilities();
mockBrowserCapabilities.setBrowserName("browserName");
mockBrowserCapabilities.setBrowserVersion("browserVersion");
return mockBrowserCapabilities;
}
But I'm getting the ClassCastException at line:
return this.prepareBrowserCapability((BrowserCapabilities)res);
cannot be cast to com.common.xxx.persistence.beans.BrowserCapabilities.

Related

How can i test that flexibleSearch works fine with .setCount()?

I have a java class that searches items, but in the method params this class receive a number of max items per query search (batchLines).
Class:
#Override
public List<OrderEntryItemModel> findOrderEntriesByStore(final BaseStoreModel store, final Date modifiedTime,
final int batchLines, final int start) {
final FlexibleSearchQuery query;
if (modifiedTime != null) {
query = new FlexibleSearchQuery(FIND_ORDER_ENTRY_ITEMS_BY_STORE_QUERY + MODIFIED_TIME_PARAM_QUERY);
query.addQueryParameter("modifiedtime", modifiedTime);
} else {
query = new FlexibleSearchQuery(FIND_ORDER_ENTRY_ITEMS_BY_STORE_QUERY);
}
query.setCount(batchLines);
query.setNeedTotal(true);
query.addQueryParameter("store", store);
query.setStart(start);
return getFlexibleSearchService().<OrderEntryItemModel>search(query).getResult();
}
So I have to test this class works fine with using .setCount(). I tried to do the test but always give me 3 and it must give me 1.
Test class:
#UnitTest
#RunWith(MockitoJUnitRunner.class)
public class DefaultLookerOrderEntryItemDaoTest {
private DefaultLookerOrderEntryItemDao lookerOrderEntryItemDao;
#Mock
private FlexibleSearchService flexibleSearchService;
#Mock
private SearchResult<OrderEntryItemModel> searchResult;
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
lookerOrderEntryItemDao = new DefaultLookerOrderEntryItemDao(flexibleSearchService);
final OrderEntryItemModel oei1 = new OrderEntryItemModel();
final OrderEntryItemModel oei2 = new OrderEntryItemModel();
final OrderEntryItemModel oei3 = new OrderEntryItemModel();
final List<OrderEntryItemModel> orderEntryItems = new ArrayList<>();
orderEntryItems.add(oei1);
orderEntryItems.add(oei2);
orderEntryItems.add(oei3);
given(flexibleSearchService.<OrderEntryItemModel>search(isA(FlexibleSearchQuery.class))).willReturn(searchResult);
given(searchResult.getResult()).willReturn(orderEntryItems);
}
#Test
public void findOrderEntries(){
given(searchResult.getCount()).willReturn(1);
final List<OrderEntryItemModel> orderEntries = lookerOrderEntryItemDao.findOrderEntriesByStore(new BaseStoreModel(), null, 1, 0);
assertEquals(1, orderEntries.size());
}
}

MapReduce - Mock with Mokito

I have the a reducer class that I wanted to write test cases:
Reduce class:
public class MyReducer extends Reducer<Text, Text, NullWritable, Text> {
private static final Logger LOG = LogManager.getLogger(MyReducer.class);
public static List<String> l1 = new ArrayList<String>();
String id = null;
private MultipleOutputs<NullWritable, Text> mos;
#Override
public void setup(final Context context) throws IOException, InterruptedException {
mos = new MultipleOutputs<NullWritable, Text>(context);
final Path[] uris = DistributedCache.getLocalCacheFiles(context.getConfiguration());
try {
final BufferedReader readBuffer1 = new BufferedReader(new FileReader(uris[0].toString()));
String line;
while ((line = readBuffer1.readLine()) != null) {
l1.add(line);
}
readBuffer1.close();
} catch (Exception e) {
LOG.error(e);
}
}
public void reduce(final Text key, final Iterable<Text> values, final Context context)
throws IOException, InterruptedException {
final String[] key1 = key.toString().split("-");
final String keyA = key1[10];
final String date = key1[1];
/* Some condition check */
mos.write(NullWritable.get(), new Text(inputEventValue), keyA + "//date=" +
date.substring(0, 4) + "-" + date.substring(4, 6));
}
#Override
public void cleanup(final Context context) throws IOException, InterruptedException {
mos.close();
}
}
Test Case looks like :
#RunWith(MockitoJUnitRunner.class)
public class MyTest {
#Mock
private MyReducer.Context mockContext;
MyReducer reducer;
MultipleOutputs<NullWritable, Text> mos;
#Before
public void setUp() {
reducer = new MyReducer();
}
#Test
public void myReducerTest() throws Exception {
MyReducer spy = PowerMockito.spy(new MyReducer());
doNothing().when(spy).setup(mockContext);
mos = new MultipleOutputs<NullWritable, Text>(mockContext);
List<Text> sline = new ArrayList<>() ;
List<String> l1 = new ArrayList<String>();
l1.add(“1234”);
sline.add(new Text(“xyz”));
Whitebox.setInternalState(MyReducer.class,”l1", l1);
Whitebox.setInternalState(MyReducer.class,"mos",mos);
reducer.reduce(new Text(“xyz-20200101-1234),sline,mockContext);
}
#After
public void tearDown() throws Exception {
/*
* this will do the clean up part
*/
verifyNoMoreInteractions(mockContext);
}
When running in Debug mode it goes to the reducer's reduce method and fails with NullPointerException where mos write statement is?
Complete Stack trace:
java.lang.NullPointerException
at org.apache.hadoop.mapreduce.lib.output.MultipleOutputs.getNamedOutputsList(MultipleOutputs.java:196)
at org.apache.hadoop.mapreduce.lib.output.MultipleOutputs.<init>(MultipleOutputs.java:324)
at MyTest.myeducerTest
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:66)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:310)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:86)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:94)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:294)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:127)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:84)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:207)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:146)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:120)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:118)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:101)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)
at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:53)
Mocking mos errors as mos is not a static.
Any suggestion.
Junit - ReduceDriver, withInput, withOutput,testRun doesn't work.
Thanks.
I tried mocking Multiple outputs as suggested:
import org.apache.hadoop.mapreduce.lib.output.MultipleOutputs;
#Mock
private MyReducer.Context mockContext;
List<String> namedOut = new ArrayList<>();
namedOut.add("NM1");
namedOut.add("NM2");
MultipleOutputs spy = PowerMockito.spy(new MultipleOutputs<>(mockContext));
when(spy, "getNamedOutputsList(mockContext)").thenReturn(namedOut);
But this gives me error : org.powermock.reflect.exceptions.MethodNotFoundException: no method found with name 'getNamedOutputsList(() anyObject())' with parameter types : [] in class org.apache.hadoop.mapreduce.lib.output.MultipleOutputs.
Looks like you did not define what mockContext.getContext() should return for your test, so it returns null and fails.
Based on this sourcecode the methods looks like this (so you might use a different version):
private static List<String> getNamedOutputsList(JobContext job) {
List<String> names = new ArrayList<String>();
StringTokenizer st = new StringTokenizer(
job.getConfiguration().get(MULTIPLE_OUTPUTS, ""), " ");
while (st.hasMoreTokens()) {
names.add(st.nextToken());
}
return names;
}
JobContext seems to refer to your mock Reducer.Context mockContext, so you need to define the appropriate behaviour so that it returns what it is supposed to return.
Note that this call originates from the constructor of MultipleOutputs.
Also take note of the static getCountersEnabled method that is invoked from the constructor and interacts with the context.
Mocking mos errors as mos is not a static.
You could probably use reflections to put a mocked version of mos into your MyReducer class.
Check here for some example on how to mock a private static field.
Edit:
If you try to mock the conig do it like this:
Configuration config = Mockito.mock(Configuration.class);
when(mockContext.getConfiguration()).thenReturn(config);
As far as I see the get that are invoked on the configuration object always provide a default value, so it shouldn't matter if the key/value pair is in there or not.

Retrofit Unit Test with Roboletric

Is there any possibility to test if Retrofit callback return success?
My code is quite simple:
#Config(constants = BuildConfig.class, sdk = 21,
manifest = "app/src/main/AndroidManifest.xml")
#RunWith(RobolectricGradleTestRunner.class)
public class RetrofitCallTest {
private MainActivity mainActivity;
#Mock
private RetrofitApi mockRetrofitApiImpl;
#Captor
private ArgumentCaptor<Callback<List<MyObject>>> callbackArgumentCaptor;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ActivityController<MainActivity> controller = Robolectric.buildActivity(MainActivity.class);
mainActivity = controller.get();
RestClient.setApi(mockRetrofitApiImpl);
controller.create();
}
#Test
public void shouldFillAdapter() throws Exception {
Mockito.verify(mockRetrofitApiImpl)
.getYourObject(callbackAgrumentCaptor.capture());
int objectsQuantity = 10;
List<MyObject> list = new ArrayList<YourObject>;
for(int i = 0; i < objectsQuantity; ++i) {
list.add(new MyObject());
}
callbackArgumentCaptor.getValue().success(list, null);
ListAdapter adapter = mainActivity.getAdapter();
assertThat(adapter .getItemCount(), equalTo(objectsQuantity));
}
It's clear - I test if my code works correctly WHEN api return success.
But is there any posibility to test IF api return success?

When trying to use Mockito to unit test sending email, I create a multipartemail object in the function, but the test fails, why?

This is my unit testing code.
public class StatsTest extends AbstractTestCase {
#Mock
//EmailInfo mockMetricsEmail = Mockito.mock(EmailInfo.class);
//EmailSenderImpl mockEmailSenderImpl = Mockito.mock(EmailSenderImpl.class);
private MultiPartEmail mockMultiPartEmail = Mockito.mock(HtmlEmail.class);
private static final String testEmailBody = "This is the test email body.";
private static final String testSender = "seemakur#amazon.com";
private static final String testRecipient = ("seemakur#amazon.com");
private static final String testEmailSubject = "subject";
private static final String testHostName = "seemakur.desktop.amazon.com";
private static final MultiPartEmail testHtmlEmail = new HtmlEmail();
EmailSenderImpl emailSenderImplObj = new EmailSenderImpl();
EmailInfo emailInfoObj = new EmailInfo(testEmailBody, testSender, testRecipient, testEmailSubject, testHostName, testHtmlEmail);
#Before
public void setUp() throws Throwable {
super.setUp();
MockitoAnnotations.initMocks(this); // will instantiate "mockMultiPartEmail"
// instantiate our class under test
}
#Test(expected = EmailException.class)
public void testSendEmail() throws EmailException, IOException {
MultiPartEmail testMultiPartEmail = Mockito.spy(new HtmlEmail());
Mockito.doReturn(mockMultiPartEmail).when(emailInfoObj).getMultiPartEmail(); //stub(spy.getMultiPartEmail()).toReturn(mockMultiPartEmail);
Mockito.when(mockMultiPartEmail.send()).thenThrow(new EmailException("Failed on multipartEmail.send(), hence could not send the email."));
// when the method under test is called
try {
//testEmailSenderImplObj.sendHtmlTableAsEmail(testMetricsEmail);
emailSenderImplObj.sendHtmlTableAsEmail(emailInfoObj); //inject mock & invoke what to test
fail("Expecting EmailException");
}catch(EmailException e){
e.printStackTrace();
}
Mockito.verify(mockMultiPartEmail).send();Mockito.doReturn(mockMultiPartEmail).when(emailInfoObj).getMultiPartEmail(); //stub(spy.getMultiPartEmail()).toReturn(mockMultiPartEmail);
}
}
i have three classes associated with this email function:
firstly below is emailInfo data object
#Data
public class EmailInfo {
private String emailBody;
private String senderEmail;
private String receiversEmails;
private String emailSubject;
private String hostName;
private MultiPartEmail multiPartEmail;
public EmailInfo(String emailBody, String senderEmail, String receiversEmails, String emailSubject, String hostName, MultiPartEmail multiPartEmail) {
this.setEmailBody(emailBody);
this.setSenderEmail(senderEmail);
this.setReceiversEmails(receiversEmails);
this.setEmailSubject(emailSubject);
this.setHostName(hostName);
this.setMultiPartEmail(multiPartEmail);
}
public String getSenderEmail() {
return senderEmail;
}
public void setSenderEmail(String senderEmail) {
this.senderEmail = senderEmail;
}
public String getEmailBody() {
return emailBody;
}
public void setEmailBody(String emailBody) {
this.emailBody = emailBody;
}
public String getReceiversEmails() {
return receiversEmails;
}
public void setReceiversEmails(String receiversEmails2) {
this.receiversEmails = receiversEmails2;
}
public String getEmailSubject() {
return emailSubject;
}
public void setEmailSubject(String emailSubject) {
this.emailSubject = emailSubject;
}
public String getHostName() {
return hostName;
}
public void setHostName(String hostName) {
this.hostName = hostName;
}
public MultiPartEmail getMultiPartEmail() {
return multiPartEmail;
}
public void setMultiPartEmail(MultiPartEmail multiPartEmail) {
this.multiPartEmail = multiPartEmail;
}
}
second class: EmailSenderImpl.java
public class EmailSenderImpl implements EmailSender{
// public MultiPartEmail getEmail(){
// return multiPartEmail;
// }
//
// public void setEmail(MultiPartEmail multiPartEmail){
// this.multiPartEmail = multiPartEmail;
// }
public void sendHtmlTableAsEmail(EmailInfo emailInfo)throws IOException, EmailException{
MultiPartEmail multiPartEmail = new HtmlEmail();
multiPartEmail.setHostName(emailInfo.getHostName());
multiPartEmail.addTo(emailInfo.getReceiversEmails());
multiPartEmail.setFrom(emailInfo.getSenderEmail());
multiPartEmail.setSubject(emailInfo.getEmailSubject());
multiPartEmail.setMsg((emailInfo.getEmailBody()).toString());
multiPartEmail.send();
}
}
lastly the EMailSender.java interface.
public interface EmailSender{
public abstract void sendHtmlTableAsEmail(EmailInfo emailInfo)throws IOException, EmailException;
}
I reason I have so many classes for one simple function is because i cannot use static methods, and i have to separate "business logic" from "function logic." And I need to have interfaces, that is necessary. If there is a better way to organize this, please let me know.
Now when I run the unit test, it fails on the line: "Mockito.doReturn(mockMultiPartEmail).when(emailInfoObj).getMultiPartEmail(); //stub(spy.getMultiPartEmail()).toReturn(mockMultiPartEmail);
");"
the error reads: org.mockito.exceptions.misusing.NotAMockException
In your original code, your problem is that on this line
Mockito.doReturn(mockMultiPartEmail).when(emailInfoObj).getMultiPartEmail();
you are trying to stub the behaviour of the created with this line
EmailInfo emailInfoObj = new EmailInfo(testEmailBody, testSender, testRecipient, testEmailSubject, testHostName, testHtmlEmail);
But this is not a mock or a spy. Mockito only lets you stub the behaviour of mocks and spies, not just arbitrary objects.
I can't tell whether you still have this issue after subsequent updates, as it's impossible to read code that's embedded in comments.

Testing a Spring MVC controller method with Spring MockMvc* classes

I am trying to test the following Spring mvc controller method:
#RequestMapping(value = "/preferences/email", method = RequestMethod.POST, produces = "text/html")
public String modifyEmail(#ModelAttribute #Validated({ Validation.EmailModification.class }) EmailInfo emailInfo, BindingResult bindingResult, Model model, Locale locale) {
Member member = memberService.retrieveCurrentMember();
if (!preferencesService.isEmailAvailable(emailInfo.getEmail())) {
if (member.getEmail().equals(emailInfo.getEmail())) {
bindingResult.addError(new FieldError("emailInfo", "email", messageSource.getMessage("controller.preferences.same_email", null, locale)));
} else {
bindingResult.addError(new FieldError("emailInfo", "email", messageSource.getMessage("controller.preferences.email_already_used", null, locale)));
}
}
if (bindingResult.hasErrors()) {
model.addAttribute("emailInfo", emailInfo);
return "preferences";
}
preferencesService.modifyEmail(member, emailInfo.getEmail());
return "redirect:/preferences/email";
}
Here is the EmailInfo bean:
#RooEquals
#RooJavaBean
public class EmailInfo {
#NotNull(groups = { Validation.EmailModification.class })
#Pattern(regexp = "^[_a-z0-9-]+(\\.[_a-z0-9-]+)*#[a-z0-9-]+(\\.[a-z0-9-]+)+$", groups = { Validation.EmailModification.class })
private String email;
private boolean activated;
private String token;
}
Here is the test class:
#ContextConfiguration
#WebAppConfiguration
#RunWith(SpringJUnit4ClassRunner.class)
public class PreferenceControllerTest {
#Autowired
private WebApplicationContext ctx;
private MockMvc mockMvc;
#Autowired
private MemberService memberService;
#Autowired
private PreferencesService preferencesService;
#Autowired
private MemberRepository memberRepository;
#Autowired
private SigninService signinService;
#Autowired
private MessageSource messageSource;
#Before
public void setup() {
mockMvc = webAppContextSetup(ctx).build();
Member currentMember = new Member();
currentMember.setEmail("currentMember#example.com");
when(memberService.retrieveCurrentMember()).thenReturn(currentMember);
when(preferencesService.isEmailAvailable("notAvailable#example.com")).thenReturn(Boolean.FALSE);
}
#Test
public void test() throws Exception {
mockMvc.perform(post("/preferences/email")//
.param("email", "newEmail#example.com"))//
.andDo(print()).andExpect(model().attributeHasNoErrors("emailInfo", "email"));
}
#Configuration
public static class testConfiguration {
#Bean
public PreferenceController preferenceController() {
return new PreferenceController();
}
#Bean
public PreferencesService preferenceService() {
return mock(PreferencesService.class);
}
#Bean
public MemberService memberService() {
return mock(MemberService.class);
}
#Bean
public MemberRepository memberRepository() {
return mock(MemberRepository.class);
}
#Bean
public SigninService signinService() {
return mock(SigninService.class);
}
#Bean
public MessageSource messageSource() {
return mock(MessageSource.class);
}
}
}
Curiously I get the following output:
MockHttpServletRequest:
HTTP Method = POST
Request URI = /preferences/email
Parameters = {email=[newEmail#example.com]}
Headers = {}
Handler:
Type = com.bignibou.controller.PreferenceController
Async:
Was async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = preferences
View = null
Attribute = emailInfo
value = com.bignibou.controller.helpers.EmailInfo#9a56c123
errors = [Field error in object 'emailInfo' on field 'email': rejected value [null]; codes []; arguments []; default message [null]]
FlashMap:
MockHttpServletResponse:
Status = 200
Error message = null
Headers = {}
Content type = null
Body =
Forwarded URL = preferences
Redirected URL = null
Cookies = []
The test fails with the above output and I am not sure why. I expected the test to pass as the email address is available.
Can anyone please help?
edit 1:
The following is not working either:
#Before
public void setup() {
mockMvc = webAppContextSetup(ctx).build();
Member currentMember = new Member();
currentMember.setEmail("currentMember#example.com");
when(memberService.retrieveCurrentMember()).thenReturn(currentMember);
when(preferencesService.isEmailAvailable(eq("notAvailable#example.com"))).thenReturn(Boolean.FALSE);
when(preferencesService.isEmailAvailable(eq("newEmail#example.com"))).thenReturn(Boolean.TRUE);
}
edit 2:
I was able to get is to work with the above edit 1 plus the test below:
#Test
public void test() throws Exception {
mockMvc.perform(post("/preferences/email")//
.param("email", "available#example.com"))//
.andDo(print())//
.andExpect(model().attributeHasNoErrors("emailInfo"));
}
With this :
.param("email", "newEmail#example.com"))//
You are setting request parameter to the string value. However you have not shown your conversion from String to EmailInfo.
In your test you are checking the field of emailInfo called email.
I am not sure what this is for ?
when(preferencesService.isEmailAvailable("notAvailable#example.com")).thenReturn(Boolean.FALSE);
What is supposed to do, you have injected your preferenceService using autowired.
Updae to answer comment.
in your controller try
String email=emailInfo.getEmail();
if(!preferencesService.isEmailAvailable(email))){ instead of if (!preferencesService.isEmailAvailable(emailInfo.getEmail())) {
Not sure, just a possible solution
Or try
when(preferencesService.isEmailAvailable(eq("newEmail#example.com"))).thenReturn(Boolean.TRUE);
when(preferencesService.isEmailAvailable(eq("notAvailable#example.com"))).thenReturn(Boolean.FALSE);
Ae you using Mockito to implement mocking?
I am not 100% sure but here is How I understand your code.
when(preferencesService.isEmailAvailable("notAvailable#example.com")).thenReturn(Boolean.FALSE);
if preferencesService.isEmailAvailable returns true then you are forcefully returning false in mock exercise
so when in mock exercise preferencesService.isEmailAvailable will always return false.
Now in your Controller
if (!preferencesService.isEmailAvailable(emailInfo.getEmail())) {
if (member.getEmail().equals(emailInfo.getEmail())) {
bindingResult.addError(new FieldError("emailInfo", "email", messageSource.getMessage("controller.preferences.same_email", null, locale)));
} else {
bindingResult.addError(new FieldError("emailInfo", "email", messageSource.getMessage("controller.preferences.email_already_used", null, locale)));
}
}
If preferencesService.isEmailAvailable is false then ! make it true so code will always go inside if Block , and you will get Field Error, and hence Test fails.