How To Create A Stub
How to create a stub for testing a one-time password service.
Stubs vs Mocks — What's the difference?
Stub
I believe the biggest distinction is that a stub you have already written with predetermined behavior. So you would have a class that implements the dependency (abstract class or interface most likely) you are faking for testing purposes and the methods would just be stubbed out with set responses. They would not do anything fancy and you would have already written the stubbed code for it outside of your test.
Mock
A mock is something that as part of your test you have to set up with your expectations. A mock is not set up in a predetermined way so you have code that does it in your test. Mocks in a way are determined at runtime since the code that sets the expectations has to run before they do anything.
Difference between Mocks and Stubs
Tests written with mocks usually follow an :
initialize -> set expectations -> exercise -> verify
pattern to testing. While the pre-written stub would follow an initialize -> exercise -> verify
.
The similarity between Mocks and Stubs.
The purpose of both is to eliminate testing all the dependencies of a class or function so your tests are more focused and simpler in what they are trying to prove.
Using stubs instead of web services.
Since we are talking about testing, it is likely that we have all the possibilities not just to put a grid in the form of a sniffer, but also to replace one of the services entirely. With this approach, the artificial service will get "frequent" requests, and we will be able to control the behavior of the destination for messages. For such purposes, there is a wonderful WireMock library. You can view its code on the project's GitHub page. The bottom line is that this is a web service with a good REST API that can be configured in almost any way. This is a JAVA library, but it has the ability to run as a standalone application, would be available JRE. And then a simple setup with detailed documentation.
How will we do it?
testing_service -> service_stub : (its log): {message}.
So we need to do a few things:
Raise the stub service and force it to accept certain messages by responding OK. this will be done by WireMock.
Ensure that messages are delivered to the stub service.
To fail what has come. There are two options — using WireMock tools for validation, or getting a list of requests from It, applying matchers to them.
Getting Started
How to raise the service manually is described in detail on the Wiremock website in the Running standalone section.
Creating a JUnit rule that will raise the service on the desired port at the start of the test and finish after the end:
@Rule
public WireMockRule wiremock = new WireMockRule(8091);
The test will look something like this:
@Test
public void shouldSend3Callbacks() throws Exception {
stubFor(any(urlMatching(".*")).willReturn(aResponse()
.withStatus(HttpStatus.OK_200).withBody("OK")));
Let our stub accept any messages.
Running as a Standalone Process
The WireMock server can be run in its own process, and configured via the Java API, JSON over HTTP or JSON files.
Once you have downloaded the standalone JAR you can run it simply by doing this:
$ java -jar wiremock-standalone-"number of last version".jar --port 8091
Command-line options
The following can optionally be specified on the command line:
--port
: Set the HTTP port number e.g. --port 9999
. Use --port 0
to dynamically determine a port.
JSON file configuration
You can also use the JSON API via files. When the WireMock server starts it creates two directories under the current one: mappings
and __files
.
To create a stub like the one above by this method, drop a file with a .json
extension under mappings
with the following content:
{
"request" : {
"urlPath" : "/get-code",
"method" : "GET",
"queryParameters" : {
"token" : {
"matches" : "access_token=([^&]*)"
},
"phone" : {
"matches" : "^((\+7|7|8)+([0-9]){10})$"
}
}
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json; charset=utf-8"
},
" jsonBody ": {"code":"1234"}
}
}
After restarting the server you should be able to do this:
$ curl http://localhost:8091/get-code/
Shutting Down
To shut down the server, post a request with an empty body to http://<host>:<port>/__admin/shutdown
.
The JUnit 4.x Rule
The JUnit rule provides a convenient way to include WireMock in your test cases. It handles the lifecycle for you, starting the server before each test method and stopping afterwards.
@Rule
public WireMockRule wireMockRule = new WireMockRule();
Also the rule's constructor can take an Options instance to override various settings.
@Rule
public WireMockRule wireMockRule = new WireMockRule(options().port(8091));
The implementation code might look like this:
/**
* The type Base api.
*/
public class BaseApi { /**
* Default constructor.
*/
public BaseApi() {
super();
//empty
return;
}
@Rule
public WireMockRule wireMockRule = new WireMockRule(options().port(8091));
/**
* Before test.
*/
@BeforeTest(alwaysRun = true)
public void beforeTest() {
wireMockRule.start();
final MockApiService mockApiService = new MockApiService();
mockApiService.startMockService();
}
/**
* After test.
*/
@AfterTest
public void afterTest() {
wireMockRule.stop();
}
}
Java (Non-JUnit) Usage
If you want to use WireMock from Java (or any other JVM language) outside of JUnit you can programmatically create, start and stop the server:
/**
* The type Base api.
*/
public class BaseApi { /**
* Value mWireMockServer.
*/
private WireMockServer mWireMockServer;
/**
* Value HTTP_PORT.
*/
public static final int HTTP_PORT = 8091;
/**
* Default constructor.
*/
public BaseApi() {
super();
//empty
return;
}
/**
* Before test.
*/
@BeforeTest(alwaysRun = true)
public void beforeTest() {
mWireMockServer = new WireMockServer(options().port( HTTP_PORT ));
mWireMockServer.start();
final MockApiService mockApiService = new MockApiService();
mockApiService.startMockService();
}
/**
* After test.
*/
@AfterTest
public void afterTest() {
mWireMockServer.stop();
}
}
Basic stubbing
The following code will configure a response with a status of 200 to be returned when the relative URL exactly matches /get-code (including query parameters token and phone). The body of the response will be "code" and a Content-Type header will be sent with a value of text-plain.
/**
* The type Mock service.
*/
public class MockApiService { /**
* The constant SUCCESS.
*/
private static final int SUCCESS = 200;
/**
* Default constructor.
*/
public MockApiService() {
super();
//empty
return;
}
/**
* Start mock service.
*/
public void startMockService() {
configureFor("localhost", HTTP_PORT );
stubFor(get(urlPathMatching("/get-code"))
.withQueryParam("token", matching("access_token=([^&]*)"))
.withQueryParam("phone", matching("^((\\+7|7|8)+([0-9]){10})$"))
.willReturn(aResponse()
.withStatus( SUCCESS )
.withHeader("Content-Type", "application/json")
.withBody("{\"code\":\"1234\"}")));
}
}
This tutorial introduced WireMock and how to set up as well as configure this library for testing of REST APIs.
This article has taught us two things:
- Stubbing is a technique that allows us to configure the HTTP response that is returned by our WireMock server when it receives a specific HTTP request.
- Creating a service for getting a one-time password.
In the next article, we will learn how to work with the one-time password service using the web UI testing tool Selenium WebDriver
How To Create A Stub
Source: https://itnext.io/how-to-create-a-stub-for-testing-a-one-time-password-service-68e0de6f6641
Posted by: engelhardtbusert.blogspot.com
0 Response to "How To Create A Stub"
Post a Comment