如何用 Sinon.JS 计时服务器响应?

How to time server responses with Sinon.JS?

我想测试我的网络应用程序如何处理服务器响应。这就是为什么我创建了一个使用 Sinon.JS to fake a server.

的测试场景

我的应用程序代码发出两个请求,在我的测试场景中,我想强制发送对第一个请求的响应对我的第二个请求的响应之后。

序列:

  1. 请求 1
  2. 请求 2
  3. 响应 2
  4. 响应 1

这是我为测试用例编写的 CoffeeScript 代码:

# Request 1
server.respondWith 'GET', "http://localhost/endpoint", [200, {"Content-Type": "application/json"}, '{"A":"A"}']
# Request 2
server.respondWith 'GET', "http://localhost/endpoint", [200, {"Content-Type": "application/json"}, '{"B":"B"}']

# My application code
...

# Response 1
server.respond()

# Response 2
server.respond()

一旦我开始测试,我的应用程序代码对 http://localhost/endpoint 的所有 REST 调用都会得到相同的响应 ({"B":"B"})。所以对我来说,看起来 Sinon.JS 总是接受来自使用 respondWith 定义的最后一个 URL 映射的响应。

但我希望我的伪造服务器 return {"B":"B"}http://localhost/endpoint 上的第一个点击。在第二次命中时,它应该 return {"A":"A"}.

是否可以这样做?

# Request 1
request_1 = server.respondWith 'GET', "http://localhost/endpoint", [200, {"Content-Type": "application/json"}, '{"A":"A"}']
# Request 2
request_2 = server.respondWith 'GET', "http://localhost/endpoint", [200, {"Content-Type": "application/json"}, '{"B":"B"}']

# My application code (makes multiple requests to the same endpoint)
...

# Response 1
request_2.respond()

# Response 2
request_1.respond()
var count = 0

$.mockjax(
  function(requestSettings){
    if(requestSettings.url === "path/to/api" && requestSettings.type === "POST"){

      return {
        response: function(origSettings){
          if (count == 0){
            this.responseText = {msg:"this is first response" }
            this.status = 200
          }
          else if(count == 1){
            //more combos
          }
          else{
            this.responseText = {msg:"this is last response" }
            this.status = 200
          }
          count = (count + 1) % 4
        }
      }
    }
  }
})

您可以使用 Pivotal 制作的 Jasmine-AJAX 库。

咖啡脚本:

it 'can handle an unlimited amount of requests and respond to each one individually after all requests have been made', ->
    jasmine.Ajax.install() # put this in beforeEach
    url = 'http://localhost/test'

    $.ajax
            dataType: 'json'
            url: url
            success: (data, textStatus, jqXHR) ->
                    # Receives {"A":"A"}
                    console.log "Response: #{JSON.stringify(data)}"

    $.ajax
            dataType: 'json'
            url: url
            success: (data, textStatus, jqXHR) ->
                    # Receives {"B":"B"}
                    console.log "Response: #{JSON.stringify(data)}"

    responses = [
            {
                    contentType: 'application/json'
                    responseText: '{"A":"A"}'
                    status: 200
            },
            {
                    contentType: 'application/json'
                    responseText: '{"B":"B"}'
                    status: 200
            }
    ]

    for i in [0...jasmine.Ajax.requests.count()]
            request = jasmine.Ajax.requests.at i
            request.respondWith responses[i]

    expect(jasmine.Ajax.requests.count()).toBe 2
    jasmine.Ajax.uninstall() # put this in afterEach

使用 count()at(),您可以获取所有按时间排序的请求并将它们放入一个数组中,例如您可以在其中移动请求并响应它们。