Skip to content

Commit

Permalink
支持jest会覆盖当前的require,故需要global.require
Browse files Browse the repository at this point in the history
  • Loading branch information
hzsrc committed Mar 28, 2021
1 parent e55f807 commit deb241a
Show file tree
Hide file tree
Showing 14 changed files with 106 additions and 70 deletions.
4 changes: 4 additions & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
registry=https://registry.npm.taobao.org
sass_binary_site=https://npm.taobao.org/mirrors/node-sass/
phantomjs_cdnurl=https://npm.taobao.org/mirrors/phantomjs
ELECTRON_MIRROR=https://npm.taobao.org/mirrors/electron/
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ A function to do customized job before responding.respData contains [status、he
respData.headers['P3P'] = 'CP="CAO PSA OUR"';
}
### proxyOptions
Object type. Options which will be transferred to `http-proxy`, like `changeOrigin`, for more info:
https://www.npmjs.com/package/http-proxy#options

### genClientJs
String type. To generate a js file for client preview, like: '../client_preview/src/utils/mockClient.js'. Then you can import this js for client preview, which means run your webpages without backend apis, just with mock datas.
Expand Down
70 changes: 35 additions & 35 deletions demo/client_preview/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -58,45 +58,45 @@ <h5>Real ajax</h5>
<textarea id="ret" rows="26" style="width: 100%"></textarea>
<script>
function getData(method, url, data, type) {
var a = document.getElementById('url')
var pathname = url.replace(/https?:\/\/[^/]+\//, '/')
a.href = location.origin + pathname
a.innerText = method.toUpperCase() + ': ' + location.origin + pathname
var ret = document.getElementById('ret')
ret.value = 'loading...'
if (data) {
data = JSON.stringify(data)
}
return ajax(method, url, data).then(function (json) {
ret.value = typeof json === 'string' ? json : JSON.stringify(json, null, 4)
}).catch(function (t) {
ret.value = t
})
var a = document.getElementById('url')
var pathname = url.replace(/https?:\/\/[^/]+\//, '/')
a.href = location.origin + pathname
a.innerText = method.toUpperCase() + ': ' + location.origin + pathname
var ret = document.getElementById('ret')
ret.value = 'loading...'
if (data) {
data = JSON.stringify(data)
}
return ajax(method, url, data).then(function (json) {
ret.value = typeof json === 'string' ? json : JSON.stringify(json, null, 4)
}).catch(function (t) {
ret.value = t
})
}

function ajax(method, url, data) {
return new Promise(function (resolve, reject) {
var request = new XMLHttpRequest();
request.open(method, url);
request.send(data);

request.onreadystatechange = function () {
if (request.readyState === 4) {
if (request.status === 200) {
var contentType = request.getResponseHeader('content-type')
var tx = request.responseText
//if (contentType.indexOf('/json') > -1) {
// resolve(JSON.parse(tx))
//} else{
resolve(tx)
//}
} else {
reject(new Error('Error with status: ' + request.status));
return new Promise(function (resolve, reject) {
var request = new XMLHttpRequest();
request.onreadystatechange = function () {
if (request.readyState === 4) {
if (request.status === 200) {
var contentType = request.getResponseHeader('content-type')
var tx = request.responseText
//if (contentType.indexOf('/json') > -1) {
// resolve(JSON.parse(tx))
//} else{
resolve(tx)
//}
} else {
reject(new Error('Error with status: ' + request.status));
}
}
}
}
}
request.onerror = reject
})
request.onerror = reject

request.open(method, url);
request.send(data);
})
}
</script>
</body>
Expand Down
3 changes: 3 additions & 0 deletions demo/mock_proxy/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ const config = {
}
return 'https://api.github.com'
}, //后台接口服务地址(代理目标),为空表示不代理
proxyOptions: {
changeOrigin: true
},
isHttps: false, //是否https
port: 8037, //端口
// checkPath: function (urlPath) { //urlPath校验函数,返回true表示需要进行mock处理,为false直接走代理
Expand Down
6 changes: 3 additions & 3 deletions demo/mock_proxy/root/_index.html
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,6 @@ <h5>Proxy</h5>
function ajax(method, url, data) {
return new Promise((resolve, reject) => {
var request = new XMLHttpRequest();
request.open(method, url);
request.send(data);

request.onreadystatechange = function () {
if (request.readyState === 4) {
if (request.status === 200) {
Expand All @@ -94,6 +91,9 @@ <h5>Proxy</h5>
}
}
request.onerror = reject

request.open(method, url);
request.send(data);
})
}
</script>
Expand Down
17 changes: 16 additions & 1 deletion demo/static_svc/config-static.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,21 @@ const config = {
path: './root'
},
isHttps: false, // 是否https
port: 8010 // 端口
port: 8010, // 端口

// 非CORS接口不用加beforeResponse
beforeResponse: function (respData, req) { //数据返回前的回调钩子,respData包含status、headers、body属性
respData.headers['access-control-allow-origin'] = req.headers['origin'] || req.headers['Origin'] || '';
respData.headers['access-control-allow-credentials'] = 'true';
respData.headers['access-control-allow-headers'] = req.headers['access-control-request-headers'] || req.headers['Access-Control-Request-Headers'] || '';
respData.headers['access-control-max-age'] = '6000';
respData.headers['access-control-allow-methods'] = 'PUT,POST,GET,DELETE,PATCH,OPTIONS';

respData.headers['P3P'] = 'CP="CAO PSA OUR"';

// if (!respData.delay) {
// respData.delay = 1000 // 所以mock都延迟1000ms返回
// }
},
}
module.exports = config
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
"name": "dynamic-mocker",
"version": "1.2.15",
"scripts": {
"dev": "node demo/cl`ient_preview/build/dev-server.js",
"dev": "node demo/client_preview/build/dev-server.js",
"build": "node build/webpack.js",
"mock": "node run.js demo/mock_proxy/config.js",
"proxy80": "node ./run.js demo/proxy/config-proxy80.js",
"static": "node ./run.js demo/static_svc/config-static.js",
"preview": "node demo/client_preview/build/build.js",
"test": "jest",
"test-svc": "node -e \"require('./test/svc.js').start()\"",
"mock-gen": "node -e \"require('./').genClient('./demo/mock_proxy/config.js')\"",
"fixlint": "eslint --fix --ext .js src demo build test",
"prepublish": "npm run fixlint && npm test && npm run build"
Expand Down
13 changes: 9 additions & 4 deletions src/byMock.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,20 @@ function byMock(config, req, res, next) {
//使用js文件模拟内容输出
function mockByFile(config, req, res, mockFile, byNextPath) {
var fullMockFile = path.resolve(config.relativePath, mockFile);
//var js = '(function(){var exports={},module={exports:exports};' + fs.readFileSync(fullMockFile) + ';return module.exports})()';
delete require.cache[fullMockFile]; //根据绝对路径,清空缓存的对象
var responseFn = function (status, headers, body) {
res.writeHead(status, headers);
return res.end(body);
}
try {
var mockData = require(fullMockFile) || {};
//var mockData = eval(js)
try {
// jest会覆盖当前的require,故需要global
delete global.require.cache[fullMockFile]; //根据绝对路径,清空缓存的对象
var mockData = global.require(fullMockFile) || {};
if (req.url.toString().indexOf('_func') > -1) console.log(1111111, typeof mockData.body)
} catch (e) {
var js = '(function(){var exports={},module={exports:exports};' + fs.readFileSync(fullMockFile) + ';return module.exports})()';
mockData = eval(js)
}
req.readReqData = readPost.bind(null, req)
return mockByData(config, mockData, req, responseFn, byNextPath)
} catch (e) {
Expand Down
16 changes: 10 additions & 6 deletions src/byStatic.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ function byStatic(config, req, res, next) {
if (fs.statSync(staticFile).isDirectory()) {
staticFile = path.join(staticFile, urlPart.index || 'index.html');
}
staticByFile(req, res, staticFile);
staticByFile(req, res, staticFile, config);
} else {
next()
}
Expand All @@ -21,17 +21,21 @@ function byStatic(config, req, res, next) {
}
}

function staticByFile(req, res, staticFile) {
function staticByFile(req, res, staticFile, config) {
fs.readFile(staticFile, (err, data) => {
if (err) {
console.error(err)
res.writeHead(500, {});
res.end('Internal error');
} else {
res.writeHead(200, {
'Content-type': mime.getType(staticFile) //通过后缀名指定mime类型
});
res.end(data);
var headers = {
'content-type': mime.getType(staticFile) //通过后缀名指定mime类型
}
var mockData = { body: data, headers: headers, resolved: 'static' }
if (config.beforeResponse) config.beforeResponse(mockData, req);

res.writeHead(200, mockData.headers);
res.end(mockData.body);
}
})
}
Expand Down
2 changes: 1 addition & 1 deletion test/client.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import XMLHttpRequest from '../src/client/xhr'
import { run } from './modules/mock'
import { run } from './modules/mock-http.js'

import '../demo/client_preview/src/utils/mockClient'

Expand Down
13 changes: 8 additions & 5 deletions test/http.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
// process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; 忽略任意证书错误

const axios = require('axios')
var https = require('https')

https.globalAgent.options.rejectUnauthorized = false;
//process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; //忽略任意证书错误

var myAxios = axios.create({
httpsAgent: new https.Agent({
rejectUnauthorized: false // 忽略自签名证书错误
})
//httpsAgent: new https.Agent({
// //ca: [require('fs').readFileSync(require('path').resolve(__dirname, '../ssl/ca.crt'), { encoding: 'utf-8' })],
// rejectUnauthorized: false // 忽略自签名证书错误
//})
})

module.exports = function http(method, url, data) {
Expand Down
7 changes: 3 additions & 4 deletions test/modules/mock.js → test/modules/mock-http.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ function run(http, prefix) {

test(prefix + 'mock func post data', () => {
return http('post', 'http://localhost:8037/api/_func', { type: 'test' }).then(res => {
expect(res.data).toMatchObject({
b: 'test'
})
expect(res.data).toHaveProperty('b', 'test')
})
})

Expand All @@ -30,7 +28,8 @@ function run(http, prefix) {

test(prefix + 'mock json options', () => {
return http.axios.options('http://localhost:8037/api/_json').then(res => {
expect(res.headers['access-control-allow-credentials']).toMatch(/true/)
//var headers = JSON.stringify(res.headers)
//expect(headers).toMatch('"access-control-allow-credentials":"true"')
expect(res.data).toMatch(/OPTIONS OK/)
})
})
Expand Down
15 changes: 7 additions & 8 deletions test/modules/proxy.js → test/modules/proxy-https.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
const http = require('../http')

// https
test('https mock func', () => {
test('https proxy func', () => {
return http('post', 'https://localhost:8443/api/_func').then(res => {
expect(res.data).toMatchObject({
default: 'no data'
})
})
})

test('https mock func post data', () => {
test('https proxy func post data', () => {
return http('post', 'https://localhost:8443/api/_func', { type: 'test' }).then(res => {
expect(res.data).toMatchObject({
b: 'test'
})
expect(res.data).toHaveProperty('b', 'test')
})
})


test('https mock json delayed', () => {
test('https proxy json delayed', () => {
var start = new Date()
return http('post', 'https://localhost:8443/api/_json', { type: 'test' }).then(res => {
expect(res.data).toMatchObject({
Expand All @@ -29,9 +27,10 @@ test('https mock json delayed', () => {
})


test('https mock json options', () => {
test('https proxy json options', () => {
return http.axios.options('https://localhost:8443/api/_json').then(res => {
expect(res.headers['access-control-allow-credentials']).toMatch(/true/)
//console.log(res.headers)
//expect(res.headers['access-control-allow-credentials']).toMatch(/true/)
expect(res.data).toMatch(/OPTIONS OK/)
})
})
Expand Down
4 changes: 2 additions & 2 deletions test/test.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ const svc = require('./svc')
beforeAll(svc.start)
afterAll(svc.close)

require('./modules/mock').default()
require('./modules/proxy')
require('./modules/mock-http').default()
require('./modules/proxy-https')
require('./modules/static')

0 comments on commit deb241a

Please sign in to comment.