package com.github.dreamhead.moco; import com.github.dreamhead.moco.helper.MocoTestHelper; import org.apache.http.client.fluent.Request; import org.apache.http.message.BasicNameValuePair; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; import java.io.IOException; import static com.github.dreamhead.moco.HttpsCertificate.certificate; import static com.github.dreamhead.moco.Moco.by; import static com.github.dreamhead.moco.Moco.eq; import static com.github.dreamhead.moco.Moco.form; import static com.github.dreamhead.moco.Moco.httpServer; import static com.github.dreamhead.moco.Moco.httpsServer; import static com.github.dreamhead.moco.Moco.log; import static com.github.dreamhead.moco.Moco.pathResource; import static com.github.dreamhead.moco.Moco.uri; import static com.github.dreamhead.moco.MocoRequestHit.atLeast; import static com.github.dreamhead.moco.MocoRequestHit.atMost; import static com.github.dreamhead.moco.MocoRequestHit.between; import static com.github.dreamhead.moco.MocoRequestHit.never; import static com.github.dreamhead.moco.MocoRequestHit.once; import static com.github.dreamhead.moco.MocoRequestHit.requestHit; import static com.github.dreamhead.moco.MocoRequestHit.times; import static com.github.dreamhead.moco.MocoRequestHit.unexpected; import static com.github.dreamhead.moco.Runner.running; import static com.github.dreamhead.moco.helper.RemoteTestUtils.port; import static com.github.dreamhead.moco.helper.RemoteTestUtils.remoteHttpsUrl; import static com.github.dreamhead.moco.helper.RemoteTestUtils.remoteUrl; import static com.github.dreamhead.moco.helper.RemoteTestUtils.root; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; import static org.mockito.Mockito.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; public class MocoRequestHitTest { private static final HttpsCertificate DEFAULT_CERTIFICATE = certificate(pathResource("cert.jks"), "mocohttps", "mocohttps"); private MocoTestHelper helper; private RequestHit hit; @Before public void setUp() throws Exception { helper = new MocoTestHelper(); hit = requestHit(); } @Test public void should_monitor_server_behavior() throws Exception { final MocoMonitor monitor = mock(MocoMonitor.class); final HttpServer server = httpServer(port(), monitor); server.get(by(uri("/foo"))).response("bar"); running(server, new Runnable() { @Override public void run() throws Exception { assertThat(helper.get(remoteUrl("/foo")), is("bar")); } }); verify(monitor).onMessageArrived(any(HttpRequest.class)); verify(monitor).onMessageLeave(any(HttpResponse.class)); verify(monitor, Mockito.never()).onException(any(Exception.class)); } @Test public void should_monitor_server_behavior_without_port() throws Exception { final MocoMonitor monitor = mock(MocoMonitor.class); final HttpServer server = httpServer(monitor); server.get(by(uri("/foo"))).response("bar"); running(server, new Runnable() { @Override public void run() throws Exception { assertThat(helper.get(remoteUrl(server.port(), "/foo")), is("bar")); } }); verify(monitor).onMessageArrived(any(HttpRequest.class)); verify(monitor).onMessageLeave(any(HttpResponse.class)); verify(monitor, Mockito.never()).onException(any(Exception.class)); } @Test public void should_verify_expected_request() throws Exception { final HttpServer server = httpServer(port(), hit); server.get(by(uri("/foo"))).response("bar"); running(server, new Runnable() { @Override public void run() throws Exception { assertThat(helper.get(remoteUrl("/foo")), is("bar")); } }); hit.verify(by(uri("/foo")), times(1)); } @Test(expected = VerificationException.class) public void should_fail_to_verify_while_expectation_can_not_be_met() throws Exception { httpServer(port(), hit); hit.verify(by(uri("/foo")), times(1)); } @Test public void should_verify_expected_request_for_at_least() throws Exception { final HttpServer server = httpServer(port(), hit); server.get(by(uri("/foo"))).response("bar"); running(server, new Runnable() { @Override public void run() throws Exception { assertThat(helper.get(remoteUrl("/foo")), is("bar")); assertThat(helper.get(remoteUrl("/foo")), is("bar")); } }); hit.verify(by(uri("/foo")), atLeast(1)); } @Test public void should_verify_expected_request_for_between() throws Exception { final HttpServer server = httpServer(port(), hit); server.get(by(uri("/foo"))).response("bar"); running(server, new Runnable() { @Override public void run() throws Exception { assertThat(helper.get(remoteUrl("/foo")), is("bar")); assertThat(helper.get(remoteUrl("/foo")), is("bar")); assertThat(helper.get(remoteUrl("/foo")), is("bar")); } }); hit.verify(by(uri("/foo")), between(1, 3)); } @Test(expected = VerificationException.class) public void should_fail_to_verify_at_least_expected_request_while_expectation_can_not_be_met() throws Exception { httpServer(port(), hit); hit.verify(by(uri("/foo")), atLeast(1)); } @Test public void should_verify_expected_request_for_at_most() throws Exception { final HttpServer server = httpServer(port(), hit); server.get(by(uri("/foo"))).response("bar"); running(server, new Runnable() { @Override public void run() throws Exception { assertThat(helper.get(remoteUrl("/foo")), is("bar")); assertThat(helper.get(remoteUrl("/foo")), is("bar")); } }); hit.verify(by(uri("/foo")), atMost(2)); } @Test(expected = VerificationException.class) public void should_fail_to_verify_at_most_expected_request_while_expectation_can_not_be_met() throws Exception { final HttpServer server = httpServer(port(), hit); server.get(by(uri("/foo"))).response("bar"); running(server, new Runnable() { @Override public void run() throws Exception { assertThat(helper.get(remoteUrl("/foo")), is("bar")); assertThat(helper.get(remoteUrl("/foo")), is("bar")); } }); hit.verify(by(uri("/foo")), atMost(1)); } @Test public void should_verify_expected_request_for_once() throws Exception { final HttpServer server = httpServer(port(), hit); server.get(by(uri("/foo"))).response("bar"); running(server, new Runnable() { @Override public void run() throws Exception { assertThat(helper.get(remoteUrl("/foo")), is("bar")); } }); hit.verify(by(uri("/foo")), once()); } @Test(expected = VerificationException.class) public void should_fail_to_verify_while_once_expectation_can_not_be_met() throws Exception { httpServer(port(), hit); hit.verify(by(uri("/foo")), times(1)); } @Test public void should_verify_unexpected_request_without_unexpected_request() throws Exception { final HttpServer server = httpServer(port(), hit); server.get(by(uri("/foo"))).response("bar"); running(server, new Runnable() { @Override public void run() throws Exception { assertThat(helper.get(remoteUrl("/foo")), is("bar")); } }); hit.verify(unexpected(), never()); } @Test public void should_verify_unexpected_request_with_unexpected_request() throws Exception { final HttpServer server = httpServer(port(), hit); running(server, new Runnable() { @Override public void run() throws Exception { try { helper.get(remoteUrl("/foo")); } catch (IOException ignored) { } } }); hit.verify(unexpected(), times(1)); } @Test(expected = VerificationException.class) public void should_fail_to_verify_while_unexpected_request_expectation_can_not_be_met() throws Exception { final HttpServer server = httpServer(port(), hit); running(server, new Runnable() { @Override public void run() throws Exception { try { helper.get(remoteUrl("/foo")); } catch (IOException ignored) { } } }); hit.verify(unexpected(), never()); } @Test(expected = IllegalArgumentException.class) public void should_throw_exception_for_negative_number_for_times() { times(-1); } @Test public void should_verify_form_data() throws Exception { final HttpServer server = httpServer(port(), hit); server.post(eq(form("name"), "dreamhead")).response("foobar"); running(server, new Runnable() { @Override public void run() throws Exception { Request request = Request.Post(root()).bodyForm(new BasicNameValuePair("name", "dreamhead")); String content = helper.executeAsString(request); assertThat(content, is("foobar")); } }); hit.verify(eq(form("name"), "dreamhead"), once()); } @Test public void should_verify_form_data_even_if_no_server_expectation() throws Exception { final HttpServer server = httpServer(port(), hit); server.response("foobar"); running(server, new Runnable() { @Override public void run() throws Exception { Request request = Request.Post(root()).bodyForm(new BasicNameValuePair("name", "dreamhead")); String content = helper.executeAsString(request); assertThat(content, is("foobar")); } }); hit.verify(eq(form("name"), "dreamhead"), once()); } @Test public void should_verify_expected_request_and_log_at_same_time() throws Exception { final HttpServer server = httpServer(port(), hit, log()); server.get(by(uri("/foo"))).response("bar"); running(server, new Runnable() { @Override public void run() throws Exception { assertThat(helper.get(remoteUrl("/foo")), is("bar")); } }); hit.verify(by(uri("/foo")), times(1)); } @Test public void should_verify_expected_request_and_log_at_same_time_for_https() throws Exception { final HttpServer server = httpsServer(port(), DEFAULT_CERTIFICATE, hit, log()); server.get(by(uri("/foo"))).response("bar"); running(server, new Runnable() { @Override public void run() throws Exception { assertThat(helper.get(remoteHttpsUrl("/foo")), is("bar")); } }); hit.verify(by(uri("/foo")), times(1)); } }