Reprint Address: http://www.techv5.com/topic/696/
The following is a brief introduction to spring's unit testing using the Java Mock tool Jmockit, which is characterized by the need not to specify a spring configuration file, any object can be mock out and associated. Controller
import com.odde.mail.model.Result;
import com.odde.mail.service.MailService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import static java.lang.String.format;
@Controller
@RequestMapping("/mail")
public class MailController {
private static final Log log = LogFactory.getLog(MailController.class);
private final ObjectMapper mapper = new ObjectMapper();
@Autowired
private MailService mailService;
@RequestMapping(value = "/send", method = RequestMethod.POST, produces = "text/plain;charset=UTF-8")
public
@ResponseBody
String send(@RequestParam("recipients") String recipients,
@RequestParam("subject") String subject,
@RequestParam("content") String content) throws Exception {
log.debug("mail controller send start");
log.debug(format("recipients:%s", recipients));
log.debug(format("subject:%s", subject));
log.debug(format("content:%s", content));
Result mailResult = mailService.send(recipients, subject, content);
String result = mapper.writeValueAsString(mailResult);
log.debug(format("result:%s", result));
log.debug("mail controller send finish");
return result;
}
}
First, let's take a look at how the controller unit tests using Jmockit are written, and the controller's function code is visible above.
Import Com.odde.mail.model.Result;
Import Com.odde.mail.service.MailService;
Import Mockit. expectations;
Import Mockit. injectable;
Import Mockit. Tested;
Import Mockit.integration.junit4.JMockit;
Import Org.junit.Test;
Import Org.junit.runner.RunWith;
Import static org.hamcrest.CoreMatchers.is;
Import static org.junit.Assert.assertThat;
@RunWith (jmockit.class) public
class Mailcontrollertest {
@Tested
mailcontroller mailcontroller;
@Injectable
private Mailservice mailservice;
@Test public
void Should_return_status_success_when_send_mail_success () throws Exception {
new Expectations () {{
mailservice.send ("test@test.com", "Test", "Test");
result = new Result ("Success");
} };
String result = Mailcontroller.send ("test@test.com", "Test", "Test");
Assertthat (result, is ("{\" status\ ": \" success \ "}"));
}
}
@RunWith (Jmockit.class): Specifies that the execution class of the unit test is jmockit.class; @Tested: This annotate refers to the test class, in this test case we want to test the mailcontroller, so we give it this label; @Injectable: This annotate can mock the object and automatically correlate it to the class being tested, without having to associate it with other files like spring's configuration file; @Expectations: The Send method of the mock object Mailservice to return a result object;
Service
Take a look at how the service unit test will be rewritten, and the same service's function code can see a post.
import com.odde.mail.model.Recipient;
import com.odde.mail.model.Result;
import com.odde.mail.repo.RecipientRepository;
import mockit.Injectable;
import mockit.NonStrictExpectations;
import mockit.Tested;
import mockit.integration.junit4.JMockit;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.List;
import static java.util.Arrays.asList;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
@RunWith(JMockit.class)
public class RecipientServiceTest {
@Tested
private RecipientService recipientService;
@Injectable
private RecipientRepository recipientRepository;
@Test
public void should_return_success_when_add_recipient_not_exist() throws Exception {
Result result = recipientService.add("Tom", "test@test.com");
assertThat(result.getStatus(), is("成功"));
}
}
Relative to controller test, there is a little less of a mock of the Recipientrepository object Findbyemail method, because the method defaults back to NULL if the method mock is not done through expectations. And the scenario we're testing is just the need for the Findbyemail method to return null, so we've also saved the mock method. The overall code after rewriting is also much less than the original, and faster. proper use of mock frames
Jmockit is a powerful feature that allows you to easily handle these test scenarios, as well as mock up static,final,private and other methods to make your unit tests work without hindrance.
But if the mock frame is overused, the bad taste of the function code is obscured. The design of the unit test allows you to find out whether some of the design of the functional code is reasonable, such as there is no tight coupling, but the use of Jmockit can make it easy for you to do unit testing in the design of unreasonable code, so that you can hardly find the problem of the function code.
So it is suggested that similar mock frameworks such as Jmockit should be used with caution, first of all, to ensure the function code design is reasonable, meet the requirements of object-oriented design, and then consider the problem of improving unit testing efficiency.
http://zhaozhiming.github.io/blog/2014/06/17/spring-mvc-unit-test-part-2/