首先与Mocha和Sinonjs进行asynchronousunit testing

我实际上是在使用我们使用mongoose的社会创build的微观框架。

为了pipe理mongoose对象,我们创build了一个modelfactory,它返回一个对应于mongoose名称对象的模型。

其实,我正在开发一个身份validation服务,在这个服务中我注入了这个模型工厂。

我需要用摩卡和sinonjs进行unit testing,但是我可能会丢失…

这是我想要testing的身份validation服务方法:

class AuthenticationService extends Service constructor: (modelFactory)-> super(modelFactory) @authorizedClientIds = [ "123456" "toto" ] @OAuthAccessTokensModel = @modelFactory.getSchema('OAuthAccessTokens') @OAuthClientsModel = @modelFactory.getSchema('OAuthClients') @OAuthUsersModel = @modelFactory.getSchema('OAuthUsers') @OAuthRefreshTokensModel = @modelFactory.getSchema('OAuthRefreshTokens') ## Get an access token from the bearer token ## getAccessToken: (bearerToken, callback)-> @OAuthAccessTokensModel.findOne({accessToken: bearerToken}, callback) module.exports = AuthenticationService 

我想testinggetAccessToken方法,但是我显然不知道如何使它工作…

我试图做一些事情:

 describe("Authentication Service", function () { var service; before(function () { ModelFactory = use('/app/core/config/database/ModelFactory'); var mock = sinon.mock(ModelFactory.getFactoryInstance([])); mock.expects("getSchema").withArgs("user").return({name:'user',getName:function(){}}); service = new AuthenticationService(mock); }); describe("getAccessToken", function () { it('should return-1 when the value is not present', function () { var proxy = once(service.getAccessToken()); mock.verify(); }); }); }); 

我应该怎么做才能正确testing它?

编辑:

我已经尝试了一些东西,但似乎很奇怪,因为我提出的结果进行比较,但结果也是如此。所以我永远不会失败的testing:x …

 describe("Authentication Service", function () { var service; before(function () { ModelFactory = use('/app/core/config/database/ModelFactory'); var factory = new ModelFactory([]); sinon.stub(factory, "getSchema").returns({findOne: sinon.stub().returns()}); service = new AuthenticationService(factory); }); describe("getAccessToken", function () { it('Check if the access token correspond to a database entry', function () { stubResult = {token: '123456'}; service.getAccessToken = sinon.stub().withArgs('1234').returns(undefined); assert.equal(service.getAccessToken(), undefined); }); }); }); 

一些帮助 ?

感谢提前

unit testing应该testing一些没有被模拟/残留的东西。

当你有一个棘手的方法handleUnknownToken()这个函数可以调用你的authentication服务。 assert()应该validation'undefined'的处理是否按预期工作。
换句话说:当你想unit testingf(x)= g()+ h()+ j(); 你可以用g()和h()来testingg()和g()的正确执行情况,用g()和j()testingh()和用g()和h()testingj()。

编辑:上面的解释是抽象的,因为我不知道mongoose/摩卡/ Sinonjs。 在下面我会试着重点描述这个案例。

当您的服务getAccessToken()被完全存根时,当您的存根定义正确时,下一个testing将成功:

 testUnknown() { constant UKNOWN_ITEM='1234'; assert.equal(service.getAccessToken(UNKNOWN_ITEM), undefined); } testTimeout() { constant DIFFICULT_ITEM='1235'; assert.equal(service.getAccessToken(DIFFICULT_ITEM), STATUS_TIMEOUT); } testRevoked() { constant REVOKED_ITEM='1236'; assert.equal(service.getAccessToken(REVOKED_ITEM), STATUS_DENIED); } testActive() { constant ACTIVE_ITEM='1237'; assert.equal(service.getAccessToken(ACTIVE_ITEM), STATUS_OK); } 

你的testing必须包含一些你不需要的逻辑。 Waht是调用getAccessToken()的代码? 像函数isTokenOK(),它会查看状态,超时后重试5次? 通过为上述testing实现的存根,您可以使用testing布尔函数isTokenOK()

 testUnknown() { assertFalse(isTokenOK(UNKNOWN_ITEM)); } testTimeout() { assertFalse(isTokenOK(DIFFICULT_ITEM)); } testRevoked() { assertFalse(isTokenOK(REVOKED_ITEM)); } testActive() { assertTrue(isTokenOK(ACTIVE_ITEM)); } 

而现在,当有人更改isTokenOK()的实现时,你的unit testing可能会失败。 当unit testing失败时,你必须看看谁是对的。 也许被撤销的令牌可以用于撤销后的前10分钟的authentication, isTokenOK(REVOKED_ITEM)应该是true。 哦,比你必须添加一个新的testingREVOKED_ITEM_YESTERDAY。