2017-07-05 14 views
0

Redisに若干新しく、ここではNodeで初心者です。RedisをNode.js(TypeScript)に統合しようとするとアサーションエラーが発生する

node-redisモジュールを、私が作業しているtypescriptノードプロジェクト(mochachai)で統合しようとしました。

私は基本的なゲッター/セッター関数を書こうとしています。残りのプロジェクトと統合することができます(私はレディスを使ってFacebookメッセンジャーボットの状態を追跡しています)。

私はsetKeyValue機能を備えたDBへの新しいキーと値のペアを記述しようとするときはいつでも、トランザクションが(redis-cliクライアントによって検証される)を通過するが、値がsetKeyValuegetValueFromKeyの両方について返さ対応していません。 DBトランザクションが成功した場合にはどうすればよいでしょうか。私が書いた

コードの実装は、以下の(私のredis_interaction.tsファイル内)である:私は実際に実行したときに、しかし

import {expect, assert} from 'chai'; 
import 'mocha'; 
import * as RedisInteraction from '../redis_interaction'; 
import {RedisResponse} from '../redis_types'; 

describe("Redis IO Works as expected", function() { 
    describe("Can GET/SET", function() { 
    it('Should be able to SET {Key, Value} Pair', function() { 
     var result = RedisInteraction.setKeyValue("key","value"); 
     expect(result).to.equal(RedisResponse.OK); 
    }); 

    it('Should be able to GET Value from Key', function() { 
     const response = RedisInteraction.getValueFromKey("key"); 
     expect(response).to.equal("value"); 
    }); 
    }); 
    describe("Can DEL", function() { 
    before(function() { 
     RedisInteraction.setKeyValue("key_to_delete","value"); 
    }); 
    it("Should be able to DEL Key from Redis DB", function() { 
     expect(RedisInteraction.deleteKeyFromRedis("key_to_delete")) 
     .to.equal(RedisResponse.OK); 
    }); 
    }); 
}); 

import * as redis from 'redis'; 
var client = redis.createClient("6379", "127.0.0.1"); 

enum RedisResponse { 
    OK, 
    Fail 
} 


    // 'Setter' Function for Key Value Pairs within Redis Database 
export function setKeyValue(key : string, value : string): RedisResponse { 
    client.set(key, value, function(err, reply) { 
    if(!err) { 
     return RedisResponse.OK; 
    } 
    }); 
    return RedisResponse.Fail; 
} 

// 'Getter' Function for Key Value Pairs within Redis Database 
export function getValueFromKey(key : string) : [string, RedisResponse] { 
    client.get(key, function(err, reply) { 
    if(!err) { 
     return[reply, RedisResponse.OK]; 
    } 
    }); 
    return["", RedisResponse.Fail]; 
} 

// 'Delete' Function for Removing Keys from within Redis Database 
export function deleteKeyFromRedis(key : string) : RedisResponse { 
    client.del(key, function(err, reply) { 
    if(!err) { 
     if(reply) { 
     return RedisResponse.OK; 
     } 
    } 
    }); 
    return RedisResponse.Fail; 
} 

私は、次のmochaのテストでこのコードをテストしますnpm test、次のエラーが表示されます。

> mocha lib/test/ 



    Redis IO Works as expected 
    Can GET/SET 
     1) Should be able to SET {Key, Value} Pair 
     2) Should be able to GET Value from Key 
    Can DEL 
     3) Should be able to DEL Key from Redis DB 


    0 passing (13ms) 
    3 failing 

    1) Redis IO Works as expected Can GET/SET Should be able to SET {Key, Value} Pair: 

     AssertionError: expected 1 to equal 0 
     + expected - actual 

     -1 
     +0 

     at Context.<anonymous> (lib/test/redis_test.js:11:38) 

    2) Redis IO Works as expected Can GET/SET Should be able to GET Value from Key: 
    AssertionError: expected [ '', 1 ] to equal 'value' 
     at Context.<anonymous> (lib/test/redis_test.js:15:40) 

    3) Redis IO Works as expected Can DEL Should be able to DEL Key from Redis DB: 

     AssertionError: expected 1 to equal 0 
     + expected - actual 

     -1 
     +0 

     at Context.<anonymous> (lib/test/redis_test.js:24:21) 

コールバックに関して何か間違っていますか?私の人生にとって、私が書いたコールバックが正しく働いていない理由を理解できません。

多くのおかげで、潜在的な冗長さについてお詫び申し上げます。

答えて

0

あなたの問題は、現在redisへの呼び出しの非同期性をどのように処理しているかです。あなたは、クライアントset関数を呼び出して、コールバックを提供...この機能で

export function setKeyValue(key : string, value : string): RedisResponse { 

    client.set(key, value, function(err, reply) { 
    if(!err) { 
     // Not a return from setKeyValue function 
     return RedisResponse.OK; 
    } 
    }); 

    // Return value from setKeyValue 
    return RedisResponse.Fail; 
} 

を探しています。実行は直ちに続き、return RedisResponse.Failのステートメントに達します。最初のreturn文は、実際にはコールバック内部からの戻り値です。これはどこでも使用されていないため破棄されます。

この非同期に対応するために、あなたのsetKeyValue関数を記述するためには、それがコールバック引数持っている必要があります:

export function setKeyValue(key : string, value : string, callback: (err: Error, response: RedisResponse) => void): void { 

    client.set(key, value, function(err, reply) { 
    // Now we know whether we succeeded 

    // If there is an error, invoke the callback with the error 
    // and a fail response 
    if(err) { 
     return callback(err, RedisResponse.Fail); 
    } 

    // Otherwise invoke it with a null error and an OK response 
    callback(null, RedisResponse.OK); 
    }); 
} 

はあなたが終了するRedisのために非同期呼び出しを待つ必要機能をテストしている、とその後、は、あなたの主張を作る - あなたはテストでコールバックを提供することにより、これを行うことができます。

it('Should be able to SET {Key, Value} Pair', function() { 
    RedisInteraction.setKeyValue("key", "value", (err, redisResponse) => { 
    expect(redisResponse).to.equal(RedisResponse.OK); 
    }); 
}); 

ただ、コーディングのこのコールバックスタイルを使用する代わりに、それは多くの場合、NiでcerはPromiseベースの実装を使用します。 node-redisはこれを提供していませんが、実装するのは比較的簡単です。私はRedisResponse列挙を削除しました。本当に必要ではないからです。約束の解決/拒否は、呼び出しが成功したかどうかを伝えます。上記の機能になるだろう(これは、上記の実装についても同様である):

export function setKeyValue(key : string, value : string): Promise<null> { 
    return new Promise((resolve, reject) => { 
    client.set(key, value, function(err, reply) { 
     if(err) { 
     // If there's an error reject the promise providing the error 
     return reject(err); 
     } 
     // Otherwise resolve it 
     resolve(); 
    }); 
} 

あなたは、その後でそれをテストすることができます。

it('Should be able to SET {Key, Value} Pair', function() { 
    RedisInteraction.setKeyValue("key", "value") 
    .then(() => { 
    // Your test has passed, no need to do anything 
    }) 
    .catch((error) => { 
    // Your test failed, do something to let mocha know 
    expect(true).to.equal(false); 
    }); 
}); 

はあなたにこのことを示した、機能していることを指摘する価値がありますあなたの質問に表示されているのは、(不必要な)RedisResponse列挙型を追加することを除いて、node-redis関数上の機能を追加していないようです。本質的にテストしているのは、node-redisがうまくいくということです。それはあなたのものではなく、ライブラリの作者の仕事です!

関連する問題