一个很好的Unit测试例子,要满足xUnit开发

package nl.enovation.commons.monitor;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

import nl.enovation.commons.IdGenerator;
import nl.enovation.ems.domain.MailSender;

import org.apache.commons.lang.math.RandomUtils;
import org.hamcrest.Description;
import org.hamcrest.Factory;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.jmock.Expectations;
import org.jmock.integration.junit4.JUnit4Mockery;
import org.jmock.lib.legacy.ClassImposteriser;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;

import static nl.enovation.commons.monitor.HasProperty.property;
import static nl.enovation.commons.monitor.HasStringCollectionValues.stringCollectionValues;
import static nl.enovation.commons.monitor.HasContent.contentValue;
import static org.junit.Assert.fail;

public class MailLoopMonitor_check_Test {

    private MailLoopMonitor mailLoopMonitor;

    protected JUnit4Mockery context = new JUnit4Mockery() {
        {
            setImposteriser(ClassImposteriser.INSTANCE);
        }
    };

    private MailSender mailSender;

    private String generatedId;

    private MailChecker mailChecker;

    @Before
    public void setUp() {
        mailLoopMonitor = new MailLoopMonitor();
        // mailSender = context.mock(MailSender.class);
        // mailChecker = context.mock(MailChecker.class);
    }

    @Test
    public void shouldSendMailWithTheConfiguredSender() throws MessagingException, IOException {
        mailSender = context.mock(MailSender.class);
        final String sender = createRandomEmailAddress();
        mailLoopMonitor.setSender(sender);
        mailLoopMonitor.setIdGenerator(createAnIdGenerator());
        mailLoopMonitor.setMailSender(mailSender);
        mailLoopMonitor.setMailChecker(createMailChecker(true));
        mailLoopMonitor.setMessage(createRandomString());
        mailLoopMonitor.setInitialWaitTime(1);
        mailLoopMonitor.setIntervalTime(1);
        mailLoopMonitor.setCheckTimes(1);
        mailLoopMonitor.setRecipient(createRandomEmailAddress());
        context.checking(new Expectations() {
            {
                one(mailSender).sendMessage(with(any(MimeMessage.class)), with(equal(sender)),
                        with(any(Collection.class)));

            }
        });      
        mailLoopMonitor.check("test");
        // verify
        context.assertIsSatisfied();
    }

    @Test
    public void shouldSendMailWithTheConfiguredRecipient() throws MessagingException, IOException {
        mailSender = context.mock(MailSender.class);
        final String recipient = createRandomEmailAddress();
        final Collection<String> recipients = new ArrayList<String>();
        recipients.add(recipient);
        mailLoopMonitor.setSender(createRandomEmailAddress());
        mailLoopMonitor.setIdGenerator(createAnIdGenerator());
        mailLoopMonitor.setMailSender(mailSender);
        mailLoopMonitor.setMailChecker(createMailChecker(true));
        mailLoopMonitor.setMessage(createRandomString());
        mailLoopMonitor.setInitialWaitTime(1);
        mailLoopMonitor.setIntervalTime(1);
        mailLoopMonitor.setCheckTimes(1);
        mailLoopMonitor.setRecipient(recipient);
        context.checking(new Expectations() {
            {
                one(mailSender).sendMessage(with(any(MimeMessage.class)), with(any(String.class)),
                        with(stringCollectionValues(recipients)));

            }
        });
        mailLoopMonitor.check("test");
        // verify
        context.assertIsSatisfied();
    }

    @Test
    public void shouldSendMailWithTheConfiguredContent() throws MessagingException, IOException {
        mailSender = context.mock(MailSender.class);
        final String messageContent = createRandomString();
        mailLoopMonitor.setSender(createRandomEmailAddress());
        mailLoopMonitor.setIdGenerator(createAnIdGenerator());
        mailLoopMonitor.setMailSender(mailSender);
        mailLoopMonitor.setMailChecker(createMailChecker(true));
        mailLoopMonitor.setMessage(messageContent);
        mailLoopMonitor.setInitialWaitTime(1);
        mailLoopMonitor.setIntervalTime(1);
        mailLoopMonitor.setCheckTimes(1);
        mailLoopMonitor.setRecipient(createRandomEmailAddress());
        context.checking(new Expectations() {
            {
                one(mailSender).sendMessage(with(contentValue(messageContent)), with(any(String.class)),
                        with(any(Collection.class)));
            }
        });
        mailLoopMonitor.check("test");
        // verify
        context.assertIsSatisfied();
    }

    @Test
    @Ignore("specification not implemented yet")
    public void shouldSendMailWithUniqueIds() throws MessagingException, IOException {
        fail("not implemented yet");
    }

    @Test
    public void shouldObtainTheUniqueIdsFromTheConfiguredIdGenerator() throws MessagingException, IOException {
        mailSender = context.mock(MailSender.class);
        mailLoopMonitor.setSender(createRandomEmailAddress());
        mailLoopMonitor.setIdGenerator(createAnIdGenerator());
        mailLoopMonitor.setMailSender(mailSender);
        mailLoopMonitor.setMailChecker(createMailChecker(true));
        mailLoopMonitor.setMessage(createRandomString());
        mailLoopMonitor.setInitialWaitTime(1);
        mailLoopMonitor.setIntervalTime(1);
        mailLoopMonitor.setCheckTimes(1);
        mailLoopMonitor.setRecipient(createRandomEmailAddress());
        context.checking(new Expectations() {
            {
                one(mailSender).sendMessage(with(property("Subject", generatedId)), with(any(String.class)),
                        with(any(Collection.class)));
            }
        });
        mailLoopMonitor.check("test");
        // verify
        context.assertIsSatisfied();
    }

    @Test
    public void shouldSendMailWithTheConfiguredMailSender() throws MessagingException, IOException {
        mailSender = context.mock(MailSender.class);
        mailLoopMonitor.setSender(createRandomEmailAddress());
        mailLoopMonitor.setIdGenerator(createAnIdGenerator());
        mailLoopMonitor.setMailSender(mailSender);
        mailLoopMonitor.setMailChecker(createMailChecker(true));
        mailLoopMonitor.setMessage(createRandomString());
        mailLoopMonitor.setInitialWaitTime(1);
        mailLoopMonitor.setIntervalTime(1);
        mailLoopMonitor.setCheckTimes(1);
        mailLoopMonitor.setRecipient(createRandomEmailAddress());
        context.checking(new Expectations() {
            {
                exactly(2).of(mailSender).sendMessage(with(any(MimeMessage.class)), with(any(String.class)),
                        with(any(Collection.class)));
            }
        });
        mailLoopMonitor.check("test");
        mailLoopMonitor.check("test");
        // verify
        context.assertIsSatisfied();
    }

    @Test
    public void shouldCheckMailWithTheConfiguredMailChecker() throws MessagingException, IOException {
        mailChecker = context.mock(MailChecker.class);
        mailLoopMonitor.setSender(createRandomEmailAddress());
        mailLoopMonitor.setIdGenerator(createAnIdGenerator());
        mailLoopMonitor.setMailSender(createMailSender());
        mailLoopMonitor.setMailChecker(mailChecker);
        mailLoopMonitor.setMessage(createRandomString());
        mailLoopMonitor.setInitialWaitTime(1);
        mailLoopMonitor.setIntervalTime(1);
        mailLoopMonitor.setCheckTimes(1);
        mailLoopMonitor.setRecipient(createRandomEmailAddress());
        context.checking(new Expectations() {
            {
                exactly(2).of(mailChecker).check(with(any(String.class)));
                will(returnValue(true));
            }
        });
        mailLoopMonitor.check("test");
        mailLoopMonitor.check("test");
        // verify
        context.assertIsSatisfied();
    }

    @Test
    public void shouldReturnStatusCriticalIfSendingMailFails() throws MessagingException, IOException {
        // status.message should contain "failed to send message"
        // status.name should equal the name parameter passed to the check()
        // method
        // status.cause should equal the exception that caused the failure
        mailSender = context.mock(MailSender.class);
        mailLoopMonitor.setSender(createRandomEmailAddress());
        mailLoopMonitor.setIdGenerator(createAnIdGenerator());
        mailLoopMonitor.setMailSender(mailSender);
        mailLoopMonitor.setMailChecker(createMailChecker(true));
        mailLoopMonitor.setMessage(createRandomString());
        mailLoopMonitor.setInitialWaitTime(1);
        mailLoopMonitor.setIntervalTime(1);
        mailLoopMonitor.setCheckTimes(1);
        mailLoopMonitor.setRecipient(createRandomEmailAddress());
        final Exception exception = new MessagingException("sending message failure.");
        context.checking(new Expectations() {
            {
                one(mailSender).sendMessage(with(any(MimeMessage.class)), with(any(String.class)),
                        with(any(Collection.class)));
                will(throwException(exception));
            }
        });
        Status status = mailLoopMonitor.check("test");
        Assert.assertEquals(Status.Code.CRITICAL, status.getCode());
        Assert.assertEquals("failed to send message", status.getMessage());
        Assert.assertEquals(exception, status.getCause());
        // verify
        context.assertIsSatisfied();
    }

    @Test
    @Ignore("specification not implemented yet")
    public void shouldWaitInitialWaitTimeAfterSendingMailBeforeCheckingMail() {
        fail("not implemented yet");
    }

    @Test
    public void shouldReturnStatusOKIfCheckingMailSucceeds() throws MessagingException, IOException {
        // status.message should contain "matched message ID " + the unique id
        // of the sent Mail
        // status.name should equal the name parameter passed to the check()
        // method
        // status.cause should be null
        mailLoopMonitor.setSender(createRandomEmailAddress());
        mailLoopMonitor.setIdGenerator(createAnIdGenerator());
        mailLoopMonitor.setMailSender(createMailSender());
        mailLoopMonitor.setMailChecker(createMailChecker(true));
        mailLoopMonitor.setMessage(createRandomString());
        mailLoopMonitor.setInitialWaitTime(1);
        mailLoopMonitor.setIntervalTime(1);
        mailLoopMonitor.setCheckTimes(1);
        mailLoopMonitor.setRecipient(createRandomEmailAddress());
        Status status = mailLoopMonitor.check("test");
        Assert.assertEquals(Status.Code.OK, status.getCode());
        Assert.assertEquals("matched message ID " + generatedId, status.getMessage());
        Assert.assertEquals("test", status.getServiceName());
        Assert.assertNull(status.getCause());
        // verify
        context.assertIsSatisfied();
    }

    @Test
    @Ignore("specification not implemented yet")
    public void shouldRetryAfterConfiguredIntervalTimeIfCheckingMailFailsAndNotYetDoneMaximumTries() {
        fail("not implemented yet");
    }

    @Test
    public void shouldReturnStatusCriticalIfCheckingMailFailsAndDoneMaximumTries() throws MessagingException,
            IOException {
        // status.message should contain "message ID " + the unique id of the
        // sent Mail + " not matched"
        // status.name should equal the name parameter passed to the check()
        // method
        // status.cause should equal the exception that caused the failure
        final int checkTimes = 3;
        mailLoopMonitor.setSender(createRandomEmailAddress());
        mailLoopMonitor.setIdGenerator(createAnIdGenerator());
        mailLoopMonitor.setMailSender(createMailSender());
        mailLoopMonitor.setMailChecker(createMailCheckerWithExactCheckTimes(false,checkTimes));
        mailLoopMonitor.setMessage(createRandomString());
        mailLoopMonitor.setInitialWaitTime(1);
        mailLoopMonitor.setIntervalTime(1);
        mailLoopMonitor.setCheckTimes(checkTimes);
        mailLoopMonitor.setRecipient(createRandomEmailAddress());
        Status status = mailLoopMonitor.check("test");
        Assert.assertEquals(Status.Code.CRITICAL, status.getCode());
        Assert.assertEquals("message ID " + generatedId + " not matched", status.getMessage());
        Assert.assertNull(status.getCause());
        // verify
        context.assertIsSatisfied();
    }

    /* new specs, add only after the specs above have been implemented */
    @Test
    public void shouldSendMailWithUniqueIdInSubjectHeaderIfSoConfigured() throws MessagingException, IOException {
        mailSender = context.mock(MailSender.class);
        mailLoopMonitor.setSender(createRandomEmailAddress());
        mailLoopMonitor.setIdGenerator(createAnIdGenerator());
        mailLoopMonitor.setMailSender(mailSender);
        mailLoopMonitor.setMailChecker(createMailChecker(true));
        mailLoopMonitor.setMessage(createRandomString());
        mailLoopMonitor.setInitialWaitTime(1);
        mailLoopMonitor.setIntervalTime(1);
        mailLoopMonitor.setCheckTimes(1);
        mailLoopMonitor.setRecipient(createRandomEmailAddress());
        context.checking(new Expectations() {
            {
                one(mailSender).sendMessage(with(property("Subject", generatedId)), with(any(String.class)),
                        with(any(Collection.class)));
            }
        });
        mailLoopMonitor.check("test");
        // verify
        context.assertIsSatisfied();
    }

    @Test
    @Ignore("specification not implemented yet")
    public void shouldSendMailWithUniqueIdInMessageIdHeaderIfSoConfigured() throws MessagingException, IOException {
        mailSender = context.mock(MailSender.class);
        mailLoopMonitor.setSender(createRandomEmailAddress());
        mailLoopMonitor.setIdGenerator(createAnIdGenerator());
        mailLoopMonitor.setMailSender(mailSender);
        mailLoopMonitor.setMailChecker(createMailChecker(true));
        mailLoopMonitor.setMessage(createRandomString());
        mailLoopMonitor.setInitialWaitTime(1);
        mailLoopMonitor.setIntervalTime(1);
        mailLoopMonitor.setCheckTimes(1);
        mailLoopMonitor.setRecipient(createRandomEmailAddress());
        context.checking(new Expectations() {
            {
                one(mailSender).sendMessage(with(property("Message-ID", "<"+generatedId+">")), with(any(String.class)),
                        with(any(Collection.class)));
            }
        });
        mailLoopMonitor.check("test");
        // verify
        context.assertIsSatisfied();
        fail("not implemented yet");
    }

    private String createRandomEmailAddress() {
        return "user" + RandomUtils.nextInt() + "@domain" + RandomUtils.nextInt() + ".example.com";
    }

    private IdGenerator<String> createAnIdGenerator() {
        final IdGenerator<String> idGenerator = context.mock(IdGenerator.class);
        generatedId = createRandomString();
        context.checking(new Expectations() {
            {
                allowing(idGenerator).getNextId();
                will(returnValue(generatedId));
            }
        });
        return idGenerator;
    }

    private String createRandomString() {
        return String.valueOf(RandomUtils.nextInt());
    }

    private MailChecker createMailChecker(boolean result) {
        final MailChecker mailChecker;
        mailChecker = context.mock(MailChecker.class);
        if (result) {
            context.checking(new Expectations() {
                {
                    allowing(mailChecker).check(with(any(String.class)));
                    will(returnValue(true));
                }
            });
        } else {
            context.checking(new Expectations() {
                {
                    allowing(mailChecker).check(with(any(String.class)));
                    will(returnValue(false));
                }
            });
        }
        return mailChecker;
    }

    private MailChecker createMailCheckerWithExactCheckTimes(boolean result, final int i) {
        final MailChecker mailChecker;
        mailChecker = context.mock(MailChecker.class);
        if (result) {
            context.checking(new Expectations() {
                {
                    exactly(i).of(mailChecker).check(with(any(String.class)));
                    will(returnValue(true));
                }
            });
        } else {
            context.checking(new Expectations() {
                {
                    exactly(i).of(mailChecker).check(with(any(String.class)));
                    will(returnValue(false));
                }
            });
        }
        return mailChecker;
    }

    private MailSender createMailSender() throws MessagingException, IOException {
        final MailSender mailSender;
        mailSender = context.mock(MailSender.class);
        context.checking(new Expectations() {
            {
                allowing(mailSender).sendMessage(with(any(MimeMessage.class)), with(any(String.class)),
                        with(any(Collection.class)));
            }
        });
        return mailSender;
    }

}

// TODO:

class HasProperty extends TypeSafeMatcher<MimeMessage> {

    private String name;

    private String value;

    public HasProperty(String name, String value) {
        this.name = name;
        this.value = value;
    }

    public void describeTo(Description description) {
    }

    @Override
    public boolean matchesSafely(MimeMessage item) {
        try {
            String[] headers = item.getHeader(name);
            if (value == null) {
                return (headers == null || headers.length == 0);
            }
            if (headers == null)
                return false;
            for (String header : headers) {
                if (header.equals(value))
                    return true;
            }
            return false;
        } catch (MessagingException e) {
            return false;
        }
    }

    @Factory
    static <T> Matcher<MimeMessage> property(String name, String value) {
        return new HasProperty(name, value);
    }
}

class HasContent extends TypeSafeMatcher<MimeMessage> {

    private String value;

    public HasContent(String value) {
        this.value = value;
    }

    public void describeTo(Description description) {
    }

    @Override
    public boolean matchesSafely(MimeMessage item) {
        try {
            String content = (String) item.getContent();
            if (value == null) {
                return false;
            }
            if (value.equals(content)) {
                return true;
            }
        } catch (IOException e) {
            return false;
        } catch (MessagingException e) {
            return false;
        }
        return false;

    }

    @Factory
    static <T> Matcher<MimeMessage> contentValue(String value) {
        return new HasContent(value);
    }
}

class HasStringValue extends TypeSafeMatcher<String> {

    private String value;

    public HasStringValue(String value) {
        this.value = value;
    }

    public void describeTo(Description description) {
    }

    @Override
    public boolean matchesSafely(String value) {
        return this.value.equals(value);
    }

    @Factory
    static <T> Matcher<String> stringValue(String value) {
        return new HasStringValue(value);
    }
}

class HasStringCollectionValues extends TypeSafeMatcher<Collection<String>> {

    private Collection<String> values;

    public HasStringCollectionValues(String value) {
        values = new ArrayList<String>(Arrays.asList(value.split(",")));
    }

    public HasStringCollectionValues(Collection<String> values) {
        this.values = values;
    }

    public void describeTo(Description description) {
    }

    @Override
    public boolean matchesSafely(Collection<String> values) {
        return this.values.containsAll(values);
    }

    @Factory
    static <T> Matcher<Collection<String>> stringCollectionValues(String values) {
        return new HasStringCollectionValues(values);
    }

    @Factory
    static <T> Matcher<Collection<String>> stringCollectionValues(Collection<String> values) {
        return new HasStringCollectionValues(values);
    }
}

class HasIntValue extends TypeSafeMatcher<Integer> {

    private Integer value;

    public HasIntValue(Integer value) {
        this.value = value;
    }

    public void describeTo(Description description) {
    }

    @Override
    public boolean matchesSafely(Integer value) {
        return this.value.equals(value);
    }

    @Factory
    static <T> Matcher<Integer> intValue(Integer value) {
        return new HasIntValue(value);
    }
}

class HasSubject extends TypeSafeMatcher<MimeMessage> {

    private String subject;

    public HasSubject(String subject) {
        this.subject = subject;
    }

    public void describeTo(Description description) {
    }

    @Override
    public boolean matchesSafely(MimeMessage item) {
        try {
            return item.getSubject().equals(subject);
        } catch (MessagingException e) {
            return false;
        }
    }

    @Factory
    static <T> Matcher<MimeMessage> subject(String subject) {
        return new HasSubject(subject);
    }
}

class HasMessageId extends TypeSafeMatcher<MimeMessage> {

    private String messageId;

    public HasMessageId(String messageId) {
        this.messageId = messageId;
    }

    public void describeTo(Description description) {
    }

    @Override
    public boolean matchesSafely(MimeMessage item) {
        try {
            return item.getMessageID().equals(messageId);
        } catch (MessagingException e) {
            return false;
        }
    }

    @Factory
    static <T> Matcher<MimeMessage> messageId(String messageId) {
        return new HasMessageId(messageId);
    }
}

class HasFileName extends TypeSafeMatcher<MimeMessage> {

    private String fileName;

    public HasFileName(String fileName) {
        this.fileName = fileName;
    }

    public void describeTo(Description description) {
    }

    @Override
    public boolean matchesSafely(MimeMessage item) {
        try {
            return item.getFileName().equals(fileName);
        } catch (MessagingException e) {
            return false;
        }
    }

    @Factory
    static <T> Matcher<MimeMessage> fileName(String fileName) {
        return new HasFileName(fileName);
    }
}

posted on 2008-07-22 10:50 刘铮 阅读(544) 评论(0)  编辑  收藏 所属分类: Jmock


只有注册用户登录后才能发表评论。


网站导航:
 
<2024年12月>
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234

导航

统计

留言簿(1)

文章分类(141)

文章档案(147)

搜索

最新评论