The previous article introduced how to use mockito to test some of our asynchronous tasks, such as asynchronous callbacks during network requests.
Now for a further introduction, a stuff that simulates our server – moco
run first
Please download this file moco.jar first , then, create a new file data.json on our desktop, open it with Notepad, paste the following stuff, the specific meaning will be introduced later
[{ "request" : { "uri" : "/hello" }, "response" : { "text" : "Hello World !!!" } } ]
Save it, then open our terminal or CMD.
Enter the following command
java -jar moco-runner-0.10.2-standalone.jar start -p 5638 -c data.json
I was relatively simple and rude, and I directly pulled the desktop file over, and CMD automatically filled in the address, so I saw that it was all on the Desktop.
Enter, after confirmation, there will be the following information
INFO Server is started at 5638
INFO Shutdown port is 52384
So now, we open our browser and type
http://localhost:5638/hello
In theory, there is no error, then the return is hello world!!!
as follows:
explain:
java -jar moco-runner-0.10.2-standalone.jar start -p 5638 -c data.json
This command means that the mock listens to the local port 5638, and the data returned by the corresponding request is in our data.json.
When a network request arrives, our mock will check data.json
and return request
the hello
corresponding data,
what we wrote is Hello World !!!
, so the browser returns this.
If there is no such request, return null.
If you want to add a new request, you can write it like this
[{"request":{ "uri": "/hello"}, "response" : { "text": "Hello World" }} ,
{"request":{ "uri": "/go"}, "response": { "text" : "go away !!!" }} ]
Add a comma and ,
then copy one more, and change the uri of the request. ok, that's it, doesn't it feel very simple? ?
So what about more complex requests? For example, in the case of post data.
complex request
Obviously our request may be so simple, at least with parameters, for example, to obtain jack
user information, the request is as follows
http://localhost:5638/user/getUser?name=jack
So how should we write our data?
{
"request" : {
"uri" : "/user/getUser",
"queries": { "name":"jack" }
},
"response" : {
"text" : "Hey. I'm jack"
}
}
regular expression
For rest style urls, Moco supports regular matching.
{
"request": {
"uri": {
"match": "/getUser/\\w+" }
},
"response": {
"text": "Find a boy."
}
}
POST , GET , PUT , DELETE and other methods
In addition to Get, Post, Put, Delete and other request modes are naturally supported. The formats are as follows, plus more method
and Forms
parameters
{
"request" :{
"method" : "post",
"uri": "/getUser",
"forms" :{
"name" : "jack"
}
},
"response" : {
"text" : "Hi. you get jack data"
}
}
We use postman to simulate, and the returned data is correct!
Headers , Cookies , StatusCode
This is to support specific headers and cookies are supported, all we need to add is headers
, cookies
and status
attributes, refer to the following
{
"request" :{
"method" : "post",
"headers" : {
"content-type" : "application/json"
}
},
"response" :{
"status" : 200,
"text" : "bar",
"cookies" :{
"login" : "true"
},
"headers" :{
"content-type" : "application/json"
}
}
}
Json
We can define the returned data as Json, the format is as follows
{
"request" :{
"uri": "/getJson",
"method" : "post",
},
"response" :{
"status" : 200,
"headers" :{
"content-type" : "application/json"
},
"json": {
"foo": "bar"
}
}
}
redirect
Introduce a redirect
{
"request" : { "uri" : "/redirect" },
"redirectTo" : "http://www.XXX.com"
}
Delay
I think this is still an important attribute, because the network environment of mobile phones is very complex, high RTT is not covered, and it is normal for the network to be delayed for tens of seconds, so we need alatency
{
"request" :{
"text" : "foo"
},
"response" :{
"latency": {
"duration": 1,
"unit": "second"
}
}
}
template
The values and return values of the above request parameters are fixed, which is naturally too rigid.
Fortunately, since version 0.8, Moco has provided a template
function to dynamically return some parameter values, although it is a beta version.
E.g:
{
"request": {
"uri": "/getUser2"
},
"response": {
"text": {
"template": "${req.queries['name']}"
}
}
}
This way, but when our request is localhost:5638/getUser2?name=nameIsJack
, then the returned data isnameIsJack
. . . . This CSDN is really, it crashes again after writing half of it. It is not possible to upload pictures, a highly available server.
In addition to the above, there are
"template": "${req.version}"
"template": "${req.method}"
"template": "${req.content}"
"template": "${req.headers['foo']}"
"template": "${req.queries['foo']}"
"template": "${req.forms['foo']}"
"template": "${req.cookies['foo']}"
These methods have been used above, so I will not explain them one by one.
Event event
Since version 0.9, mock provides the event method. What does it mean?
Sometimes, when we request some specific interfaces, we may need to request other addresses in order to complete the request.
For example, OAuth, etc., involving a third party. At this time, Event comes in handy
{
"request": {
"uri" : "/event"
},
"response": {
"text": "event"
},
"on": {
"complete": {
"get" : {
"url" : "http://another_site/OAuth?xxx=xxxx"
}
}
}
}
In this way, we can wait to verify the permission part before returning the result.
Asynchronous request Asynchronous
The previous requests are all synchronous by default, which means that the result will not be returned to the client until the server has finished processing.
If your actual situation is not like this and you need to use asynchronous, then starting from version 0.9, there is this function. Also you can delay 5 seconds like this
{
"request": {
"uri" : "/event"
},
"response": {
"text": "event"
},
"on": {
"complete": {
"async" : "true",
"latency" : 5000,
"post" : {
"url" : "http://www.baidu.com",
"content": "content"
}
}
}
}
sub-module
There are obviously many requests, such as
the userApi business of the user module, the chatApi business of the chat module, etc.
If the business of these different modules is written in one file, it will be too ugly. For this reason , some sensible solutions are
neededTodoList
[ { "context": "/user", "include": "user.json" }, { "context": "/todo", "include": "todo.json" } ]
In this way, when we access
http://localhost:12306/user/create
and http://localhost:12306/todo/getAll
, we
will skip to the corresponding json and process it again
//user
[ { "request" : { "uri" : "/create" }, "response" : { "text" : "这是创建用户请求" } } ]
//todo
[ { "request" : { "uri" : "/getAll" }, "response" : { "text" : "这是获取用户所有Todo的请求" } } ]
Moco supports the introduction of other configuration files in the global configuration file, so that configuration files can be defined by service for easy management.
After configuring the file, you can import it in the global file: the
global configuration is as follows:
java -jar moco-runner-standalone.jar start -p 5638 -g data.json
Note that at this time, you need to -g
load the global configuration file through parameters. , is not used -c
anymore
Otherwise, the configuration file parsing will report an error.