2016-08-22 80 views
0

测试的承诺我得到这个错误,当我测试我的代码:导致未定义值

1) Sourcerer Testing: getStatusCode : 
    Error: Expected undefined to equal 200 

我不知道为什么我收到在我的测试undefined但是当我运行的代码,我得到200。这可能是从没有处理promises正确

Test code: 

import expect from 'expect'; 
import rp from 'request-promise'; 
import Sourcerer from './sourcerer'; 


describe("Sourcerer Testing: ",() => { 
    let sourcerer = new Sourcerer(null); 
    const testCases = { 
     "https://www.google.com": 200, 
     // "www.google.com": 
    }; 

    describe("getStatusCode",() => { 
     it("",() => { 
      for (let testCase in testCases) { 
       sourcerer.setSourcererUrl(testCase); 
       expect(sourcerer.url).toEqual(testCase); 
       expect(sourcerer.getStatusCode()).toEqual(testCases[testCase]); 
      } 
     }); 
    }); 
}); 

代码:

import rp from 'request-promise'; 

export default class Sourcerer { 
    constructor(url) { 
     this.options = { 
      method: 'GET', 
      url, 
      resolveWithFullResponse: true 
     }; 
     this.payload = {}; 
    } 

    setSourcererUrl(url) { 
     this.url = url; 
    } 

    getSourcererUrl() { 
     return this.url; 
    } 

    analyzeSourcePage() { 
     rp(this.options).then((res) => { 
      console.log(res); 
     }).catch((err) => { 
      console.log("ERROR"); 
      throw(err); 
     }); 

    } 

    getStatusCode() { 
     rp(this.options).then((res) => { 
      console.log(res.statusCode); 
      return res.statusCode; 
     }).catch((err) => { 
      console.log("STATUS CODE ERROR"); 
      return 0; 
     }); 
    } 
} 

回答

1

getStatusCode不会返回任何东西。它应该返回一个承诺:

getStatusCode() { 
    return rp(this.options)... 
} 

该规范将在这种情况下会失败,因为它需要承诺对象的值为200

它是更为复杂,因为产品的规格有异步有几个承诺在规格完成之前应该等待。它应该像

it("",() => { 
     let promises = []; 
     for (let testCase in testCases) { 
      sourcerer.setSourcererUrl(testCase); 
      let statusCodePromise = sourcerer.getStatusCode() 
      .then((statusCode) => { 
       expect(sourcerer.url).toEqual(testCase); 
       expect(statusCode).toEqual(testCases[testCase]); 
      }) 
      .catch((err) => { 
       throw err; 
      }); 
      promises.push(statusCodePromise); 
     } 

     return promises; 
    }); 

co提供一个真棒替代Promise.all用于流量控制:

it("", co.wrap(function*() { 
     for (let testCase in testCases) { 
      sourcerer.setSourcererUrl(testCase); 
      expect(sourcerer.url).toEqual(testCase); 
      let statusCode = yield sourcerer.getStatusCode(); 
      expect(statusCode).toEqual(testCases[testCase]); 
     } 
    }); 
+1

@Liondancer还应该注意到,该规范并没有通过异步得。 HTTP请求可以被模拟(例如''nock'),而Sinon和Jasmine都提供了模拟定时器功能并使规范同步的方法。 – estus

1

免责声明:我不会运行一个for循环中的一个它(),因为我想知道哪些迭代失败。认为有办法实现这一点,但这是另一回事。此外,这很大程度上取决于你的测试跑步者,但这里有一些我认为有用的经验法则。

但是对于你所要求的,测试不应该评估,直到承诺解决。有时(例如摩卡),这意味着从it()内部函数返回承诺。有时,这意味着要完成一个功能并在准备好测试进行评估时调用它。如果你在你的测试框架上提供了更多的信息,我可以帮助(其他人肯定会)