Loading .eml files into javax.mail.Messages - unit-testing

I'm trying to unit test a method which processes javax.mail.Message instances.
I am writing a converter to change emails which arrive in different formats and are then converted into a consistent internal format (MyMessage). This conversion will usually depend on the from-address or reply-address of the email, and the parts of the email, the subject, and the from- and reply-addresses will be required for creating the new MyMessage.
I have a collection of raw emails which are saved locally as .eml files, and I'd like to make a unit test which loads the .eml files from the classpath and converts them to javax.mail.Message instances. Is this possible, and if so, how would it be done?

After a few tests, I finally successfully loaded a message using the MimeMessage(Session, InputStream) public constructor (as opposed to the Folder-based protected one cited in the other response).
import java.io.FileInputStream;
import java.io.InputStream;
import javax.mail.internet.MimeMessage;
public class LoadEML {
public static void main(String[] args) throws Exception {
InputStream is = new FileInputStream(args[0]);
MimeMessage mime = new MimeMessage(null, is);
System.out.println("Subject: " + mime.getSubject());
}
}

My problem came from using Mockito to mock the javax.mail.Folder required by javax.mail.internet.MimeMessage's constructor MimeMessage(Folder, InputStream, int). This calls the constructor for javax.mail.Message Message(Folder, int) which then accesses folder.store.session. This resulted in a NullPointerException being thrown by the constructor for MimeMessage.
Solution:
class ClasspathMimeMessage extends MimeMessage {
private ClasspathMimeMessage(Folder folder, InputStream is, int msgnum) throws MessagingException {
super(folder, is, 0);
}
public static MimeMessage create(String resourceName) {
Class<PopEmailMmsReceiverTest> loaderClass = PopEmailMmsReceiverTest.class;
InputStream is = loaderClass.getResourceAsStream(resourceName);
Folder inbox = new MyFolder();
try {
return new ClasspathMimeMessage(inbox, is, 0);
} catch (MessagingException ex) {
throw new RuntimeException("Unable to load email from classpath at " + loaderClass.getResource(resourceName).toString());
}
}
}
class MyFolder extends Folder {
MyFolder() {
super(createMockStore());
}
private static Store createMockStore() {
return mock(Store.class);
}
public void appendMessages(Message[] msgs) throws MessagingException {
}
public void close(boolean expunge) throws MessagingException {
}
public boolean create(int type) throws MessagingException {
return false;
}
public boolean delete(boolean recurse) throws MessagingException {
return false;
}
public boolean exists() throws MessagingException {
return false;
}
public Message[] expunge() throws MessagingException {
return null;
}
public Folder getFolder(String name) throws MessagingException {
return null;
}
public String getFullName() {
return null;
}
public Message getMessage(int msgnum) throws MessagingException {
return null;
}
public int getMessageCount() throws MessagingException {
return 0;
}
public String getName() {
return null;
}
public Folder getParent() throws MessagingException {
return null;
}
public Flags getPermanentFlags() {
return null;
}
public char getSeparator() throws MessagingException {
return 0;
}
public int getType() throws MessagingException {
return 0;
}
public boolean hasNewMessages() throws MessagingException {
return false;
}
public boolean isOpen() {
return false;
}
public Folder[] list(String pattern) throws MessagingException {
return null;
}
public void open(int mode) throws MessagingException {
}
public boolean renameTo(Folder f) throws MessagingException {
return false;
}
}
This looks very ugly to me, so if anyone has a better suggestion, I'd be delighted to hear it.

Related

Playframework 1.2.7 interceptors

There is a problem with PlayF 1.2.7 interceptors.
I have a controller AuthCtl with #Before annotation.
And another controller class AlarmCtl which uses #With(AuthCtl.class).
public class AuthCtl extends Controller {
public static final String KMK_AUTH_TOKEN = "KMK_AUTH_TOKEN";
public static final String KMK_USER_ID = "KMK_USER_ID";
#Before
static void checkAuthorization() throws KomekException {
if (request.cookies.containsKey(AuthCtl.KMK_AUTH_TOKEN) &&
request.cookies.containsKey(AuthCtl.KMK_USER_ID)) {
//Something
} else {
throw new UnauthorizedException();
}
}
#Catch
static void handleExceptions(Throwable t) {
response.status = ((KomekException)t).getErrorCode();
response.accessControl("*");
response.contentType = "application/json";
renderText(t.toString());
}
}
#With(AuthCtl.class)
public class AlarmCtl extends Controller {
//Something
}
So when I'm throwing exception in the checkAuthorization method my handleExceptions method doesn't intercept it. What's the problem?
You need to specify what type of exception(s) you want to catch.
So in your case it would need to be written like this:
#Catch(KomekException.class)
static void handleExceptions(Throwable t) {
response.status = ((KomekException)t).getErrorCode();
response.accessControl("*");
response.contentType = "application/json";
renderText(t.toString());
}
Or, for a general (kind of dirty) catch all, use the root Exception class:
#Catch(Exception.class)
static void handleExceptions(Throwable t) {
response.status = ((KomekException)t).getErrorCode();
response.accessControl("*");
response.contentType = "application/json";
renderText(t.toString());
}

JMockit: Mocking all implementations of an interface

Is it possible to mock all implementations of an interface?
I want to mock the WatchService interface like the following
public class ServiceTest {
#Test
public void callTest(
#Capturing
#Injectable
final WatchService ws
) throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
new MockUp<ServiceTest>() {
#Mock(invocations = 1)
public void onChange() {
latch.countDown();
}
};
new NonStrictExpectations() {
{
ws.take();
result = new Delegate() {
WatchKey take(Invocation inv) {
System.out.println("> " + inv.getInvokedInstance());
try {
new File("target/newFile").createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
return inv.proceed();
}
};
}
};
final Thread thread = new Thread() {
#Override
public void run() {
final Path target = Paths.get("target");
final FileSystem fs = target.getFileSystem();
try {
try (WatchService watcher = fs.newWatchService()) {
target.register(watcher, ENTRY_CREATE);
while (!Thread.currentThread().isInterrupted()) {
WatchKey take = watcher.take();
onChange();
System.out.println("take " + take);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
thread.start();
assertTrue("", latch.await(5, TimeUnit.SECONDS));
thread.interrupt();
}
private void onChange() {
System.out.println("CHANGE");
}
How can I accomplish that?
You can use the #Capturing annotation on a mock field or mock parameter of the interface type. Below we have a complete example test (minus imports).
public class CapturingAndProceedingTest {
static class WatchKey { String key; WatchKey(String k) {key = k;} }
public interface WatchService { public abstract WatchKey take(); }
static class WatchServiceImpl1 implements WatchService {
#Override public WatchKey take() { return new WatchKey("Abc"); }
}
static class WatchServiceImpl2 implements WatchService {
#Override public WatchKey take() { return new WatchKey("123"); }
}
#Test
public void mockAllImplementationsOfAnInterface(
#Capturing // so that all implementing classes are mocked
#Injectable // so that Invocation#proceed() is supported
final WatchService watchService
) {
final List<WatchService> services = new ArrayList<>();
// Record an expectation that will match all calls to
// WatchService#take(), on any class implementing the interface.
new NonStrictExpectations() {{
watchService.take();
result = new Delegate() {
WatchKey take(Invocation inv) throws IOException {
// Do something here...
WatchService service = inv.getInvokedInstance();
services.add(service);
// ...then proceed to the real implementation.
return inv.proceed();
}
};
}};
// Instantiate and use different implementations of the interface.
WatchServiceImpl1 impl1 = new WatchServiceImpl1();
assertEquals("Abc", impl1.take().key);
WatchServiceImpl2 impl2 = new WatchServiceImpl2();
assertEquals("123", impl2.take().key);
assertEquals(Arrays.asList(impl1, impl2), services);
System.out.println(services);
}
}
See the JMockit Tutorial for more examples.

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.

EntityManger null in seam unit tests

Below is the code I am trying to test, but getting null pointer exception on entityManager.find coz entityManager = null. Any suggestions?
#Name("UserProfileConverter")
#BypassInterceptors
#Converter(forClass= UserProfile.class)
public class UserProfileConverter implements javax.faces.convert.Converter {
#Logger
private static Log logger;
public Object getAsObject(FacesContext arg0, UIComponent uiComponent, String s) {
EntityManager entityManager = (EntityManager) Component.getInstance("entityManager");
UserProfile p;
if(s == null || s.equals("null")) {
return null;
} else {
try {
long i = Long.parseLong(s);
return entityManager.find(UserProfile.class, i);
} catch (NumberFormatException e) {
logger.error(e);
} catch (SecurityException e) {
logger.error(e);
}
}
return null;
}
public String getAsString(FacesContext context, UIComponent uiComponetn, Object arg2) {
return ((CsaRole)arg2).getCsaRoleId() + "";
}
}
Here is my test class..
public class UserProfileConverterTest extends SeamTest {
private UserProfileConverter converter;
private FacesContext mockFacesContext;
private UIComponent mockUiComponent;
private final static Logger logger = Logger.getLogger(UserProfileConverterTest.class);
#BeforeClass
public void setup() {
converter = new UserProfileConverter();
}
#Test
public void testGetAsObject()
throws Exception {
new ComponentTest() {
#Override
protected void testComponents() throws Exception {
String value = "11111111111";
converter.getAsObject(mockFacesContext, mockUiComponent, value);
}
}.run();
}
}
public class UserProfileConverterTest extends SeamTest {
EntityManager mockEntityManager;
private UserProfileConverter converter;
UIComponent mockUiComponent = null;
MockFacesContext mockFacesContext = null;
#BeforeClass
public void setup() {
converter = new CsaUserProfileConverter();
mockEntityManager = EasyMock.createMock(EntityManager.class);
}
class BaseComponentTest extends ComponentTest {
protected void testComponents() throws Exception {
ScopeType.EVENT.getContext().set("entityManager", mockEntityManager);
}
}
#Test
public void testGetAsObject() throws Exception {
new BaseComponentTest() {
protected void testComponents() throws Exception {
super.testComponents();
UserProfile expectedResult = new UserProfile();
EasyMock.expect(mockEntityManager.find(UserProfile.class,1L)).andReturn(expectedResult);
//Replay Mock
EasyMock.replay(mockEntityManager);
Object target = converter.getAsObject(mockFacesContext,mockUiComponent,"1");
Assert.assertEquals(expectedResult, target);
//Verify the Mock
EasyMock.verify(mockEntityManager);
}
}.run();
}

Mocking, Unit Testing (NUnit) setup problem with HttpHandler

This post relates to two other posts, here and here.
I'm new to Unit Testing & Mocking. I have a test fixture that is trying to mock a HttpContext object including the response and request. I think the test code is not setup properly, as after calling the handler I get an error immediately. There error I am getting is:
UnitTests.UADHandlerFixture.Request_Is_Object:
System.NullReferenceException : Object reference not set to an instance of an object.
at Abstract.BaseHttpHandler.get_Request() in BaseHttpHandler.cs:line 21
at Abstract.BaseHttpHandler.get_IsRequestFromUAD() in BaseHttpHandler.cs:line 23
at Handlers.UADTimeHttpHandler.ProcessRequest(HttpContextBase context) in UADTimeHttpHandler.cs:line 19
at UnitTests.UADHandlerFixture.Request_Is_Object() in UADHttpHanderTests.cs:line 47
The test code is this:
[TestFixture]
public class UADHandlerFixture
{
private Mock<HttpContextBase> _mockHttpContext;
private Mock<HttpRequestBase> _mockHttpRequest;
private Mock<HttpResponseBase> _mockHttpResponse;
private UADTimeHttpHandler _handler;
private WindsorContainer _container;
[SetUp]
public void Init()
{
_mockHttpRequest = new Mock<HttpRequestBase>();
_mockHttpResponse = new Mock<HttpResponseBase>();
_mockHttpContext = new Mock<HttpContextBase>();
_container = new WindsorContainer();
_container.AddComponent<ILogger, FakeLogger>();
_container.AddComponent<IDataRepository, FakeDataRepository>();
_mockHttpContext.SetupGet(x => x.Application[0]).Returns(_container);
_mockHttpContext.SetupGet(x => x.Request).Returns(_mockHttpRequest.Object);
_mockHttpContext.SetupGet(x => x.Response).Returns(_mockHttpResponse.Object);
_handler = new UADTimeHttpHandler();
}
[Test]
public void Request_Is_Object()
{
_handler.ProcessRequest(_mockHttpContext.Object);
}
}
Handler:
public class UADTimeHttpHandler : BaseHttpHandler
{
public override void ProcessRequest(HttpContextBase context)
{
if (IsRequestFromUAD)
{
Logger.Log("Log stuff");
DataRepository.Write("DB stuff");
ReturnResponse(HttpStatusCode.OK, DateTime.Now.ToString());
}
else
ReturnResponse(HttpStatusCode.BadRequest);
}
}
BaseHandler:
public abstract class BaseHttpHandler : IHttpHandler
{
private HttpContext _httpContext;
private ILogger _logger;
private IDataRepository _dataRepository;
protected ILogger Logger { get { return _logger; } }
protected IDataRepository DataRepository { get { return _dataRepository; } }
protected HttpContext Context { get { return _httpContext; } }
protected HttpRequest Request { get { return _httpContext.Request; } }
protected HttpResponse Response { get { return _httpContext.Response; } }
protected bool IsRequestFromUAD { get { return Request.UserAgent == null ? false : Request.UserAgent.Equals("UAD"); } }
public virtual bool IsReusable { get { return false; } }
public void ProcessRequest(HttpContext context)
{
WindsorContainer container = (WindsorContainer)context.Application[0];
_logger = container.Resolve<ILogger>();
_dataRepository = container.Resolve<IDataRepository>();
_httpContext = context;
ProcessRequest(new HttpContextWrapper(context));
}
protected virtual void ReturnResponse(HttpStatusCode httpStatus)
{
Response.StatusCode = (int)httpStatus;
}
protected virtual void ReturnResponse(HttpStatusCode httpStatus, string response)
{
Response.StatusCode = (int)httpStatus;
Response.Write(response);
}
protected virtual string GetInputStream()
{
using (var reader = new StreamReader(Request.InputStream))
{
return reader.ReadToEnd();
}
}
public abstract void ProcessRequest(HttpContextBase context);
}