JasmineµÄ¿ª·¢ÍŶÓÀ´×ÔPivotalLabs£¬ËûÃÇÒ»¿ªÊ¼¿ª·¢µÄJavaScript²âÊÔ¿ò¼ÜÊÇJsUnit£¬À´Ô´ÓÚÖøÃûµÄJAVA²âÊÔ¿ò¼ÜJUnit¡£JsUnitÊÇxUnitµÄJavaScriptʵÏÖ¡£µ«ÊÇJsUnitÔÚ2009Äêºó¾ÍÒѾֹͣά»¤ÁË£¬ËûÃÇÍÆ³öÁËÒ»¸öеÄBDD¿ò¼ÜJasmine¡£Jasmine²»ÒÀÀµÓÚÈκοò¼Ü£¬ËùÒÔÊÊÓÃÓÚËùÓеÄJavascript´úÂë¡£
ËùνBDD£¨ÐÐΪÇý¶¯¿ª·¢£¬Behaviour Driven Development£©£¬ÊÇÒ»ÖÖеÄÃô½Ý¿ª·¢·½·¨¡£Dan
North¶ÔBDD¸ø³öµÄ¶¨ÒåΪ£º
BDDÊǵڶþ´úµÄ¡¢ÓÉÍâ¼°Äڵġ¢»ùÓÚÀ(pull)µÄ¡¢¶à·½ÀûÒæÏà¹ØÕßµÄ(stakeholder)¡¢¶àÖÖ¿ÉÀ©Õ¹µÄ¡¢¸ß×Ô¶¯»¯µÄÃô½Ý·½·¨¡£ËüÃèÊöÁËÒ»¸ö½»»¥Ñ»·£¬¿ÉÒÔ¾ßÓдøÓÐÁ¼ºÃ¶¨ÒåµÄÊä³ö£¨¼´¹¤×÷Öн»¸¶µÄ½á¹û£©£ºÒѲâÊÔ¹ýµÄÈí¼þ¡£
BDDÓëTDD£¨Test Driven Development £©µÄÖ÷񻂿±ðÊÇ£¬Ê¹µÃ·Ç³ÌÐòÈËÔ±Ò²ÄܲÎÓëµ½²âÊÔÓÃÀýµÄ±àдÖÐÀ´£¬´ó´ó½µµÍÁ˿ͻ§¡¢Óû§¡¢ÏîÄ¿¹ÜÀíÕßÓ뿪·¢ÕßÖ®¼äÀ´»Ø·ÒëµÄ³É±¾¡£ËùÒÔBDD¸ü¼Ó×¢ÖØÒµÎñÐèÇó¶ø²»ÊǼ¼Êõ[1]¡£
ÏÂÔØ
ÔÚJasmineµÄGithub¹Ù·½Ö÷Ò³£ºhttps://github.com/jasmine/jasmine
ÕÒµ½ÉÏ·½µÄreleases£¬µã»÷»áÌø×ªµ½https://github.com/jasmine/jasmine/releases¡£
ÏÂÔØÒÑ·¢²¼µÄzip°ü£¬±ÈÈçÏÂÔØµ±Ç°£¨2015-03-09£©µÄ×îа汾Ϊ£ºjasmine-standalone-2.2.0.zip
Ŀ¼½á¹¹
½âѹ֮ºó£¬¿ÉÒÔ¿´µ½ÓÐ1¸öhtmlÎļþºÍ3¸öÎļþ¼Ð¡£
1.lib£º´æ·ÅÁËÔËÐвâÊÔ°¸ÀýËù±ØÐëµÄÎļþ£¬ÆäÄÚ°üº¬jasmine-2.2.0Îļþ¼Ð¡£¿ÉÒÔ½«²»Í¬°æ±¾µÄJasmine·ÅÔÚlibÏ£¬ÒÔ±ãʹÓÃʱÇл»¡£
jasmine.js£ºÕû¸ö¿ò¼ÜµÄºËÐÄ´úÂë¡£
jasmine-html.js£ºÓÃÀ´Õ¹Ê¾²âÊÔ½á¹ûµÄjsÎļþ¡£
boot.js£ºjasmine¿ò¼ÜµÄµÄÆô¶¯½Å±¾¡£ÐèҪעÒâµÄÊÇ£¬Õâ¸ö½Å±¾Ó¦¸Ã·ÅÔÚjasmine.jsÖ®ºó£¬×Ô¼ºµÄjs²âÊÔ´úÂë֮ǰ¼ÓÔØ¡£
jasmine.css£ºÓÃÀ´ÃÀ»¯²âÊÔ½á¹û¡£
2.spec£º´æ·Å²âÊԽű¾¡£
PlayerSpec.js£º¾ÍÊÇÕë¶ÔsrcÎļþ¼ÐϵÄPlayer.jsËùдµÄ²âÊÔÓÃÀý¡£
SpecHelper.js£ºÓÃÀ´Ìí¼Ó×Ô¶¨ÒåµÄ¼ìÑ鹿Ôò£¬Èç¹û¿ò¼Ü±¾ÉíÌṩµÄ¹æÔò£¨ÖîÈçtoBe,toNotBeµÈ£©²»ÊÊÓ㬾ͿÉÒÔ¶îÍâÌí¼Ó×Ô¼ºµÄ¹æÔò£¨ÔÚ±¾ÎļþÖÐÌí¼ÓÁË×Ô¶¨ÒåµÄ¹æÔòtoBePlaying£©¡£
3. src£º´æ·ÅÐèÒª²âÊÔµÄjsÎļþ¡£JasmineÌṩÁËÒ»¸öExample£¨Player.js£¬Song.js£©¡£
4.SpecRunner.html£ºÔËÐвâÊÔÓÃÀýµÄ»·¾³¡£Ëü½«ÉÏÃæ3¸öÎļþ¼ÐÖÐһЩ±ØÒªµÄÎļþ¶¼°üº¬Á˽øÀ´¡£Èç¹ûÄãÏ뽫×Ô¼ºµÄ²âÊÔÌí¼Ó½øÀ´µÄ»°£¬ÄÇô¾ÍÐÞ¸ÄÏàÓ¦µÄ·¾¶¡£
ÆäÖУ¬specÎļþ¼Ð£¬srcÎļþ¼ÐºÍSpecRunner.htmlÎļþÊÇJasmineÌṩµÄÒ»¸öÍêÕûʾÀý£¬ÓÃä¯ÀÀÆ÷´ò¿ª
SpecRunner.html£¬¼´¿É¿´µ½Ö´ÐеĽá¹û¡£
SpecRunner.htmlÔËÐвâÊÔÓÃÀýµÄÀý×Ó£º
<html> <head> <meta charset="utf-8"> <title>Jasmine Spec Runner v2.2.0</title>
<link rel="shortcut icon" type="image/png"
href="lib/jasmine-2.2.0/jasmine_favicon.png">
<link rel="stylesheet" href="lib/jasmine-2.2.0/jasmine.css">
<script src="lib/jasmine-2.2.0/jasmine.js"></script>
<script src="lib/jasmine-2.2.0/jasmine-html.js"></script>
<script src="lib/jasmine-2.2.0/boot.js"></script>
<!-- include source files here... -->
<script src="src/Player.js"></script>
<script src="src/Song.js"></script>
<!-- include spec files here... -->
<script src="spec/SpecHelper.js"></script>
<script src="spec/PlayerSpec.js"></script>
</head>
<body></body>
</html> |
ºËÐĸÅÄî
¿ò¼ÜÖеÄһЩºËÐĸÅÄ¿ÉÒԲο¼¹Ù·½ÎĵµÖеĽéÉÜ[2]¡£ÏÂÃæ½øÈë°áשģʽ£º
Suites
Suite±íʾһ¸ö²âÊÔ¼¯£¬ÒÔº¯Êýdescribe(string, function)·â×°£¬Ëü°üº¬2¸ö²ÎÊý£º
string£º²âÊÔ×éÃû³Æ£¬
function£º²âÊÔ×麯Êý¡£
Ò»¸öSuite(describe)°üº¬¶à¸öSpecs(it)£¬Ò»¸öSpecs(it)°üº¬¶à¸ö¶ÏÑÔ£¨expect£©¡£
SetupºÍTeardown²Ù×÷
JasmineµÄSetupºÍTeardown²Ù×÷£¨SetupÔÚÿ¸ö²âÊÔÓÃÀýSpecÖ´ÐÐ֮ǰ×öһЩ³õʼ»¯²Ù×÷£¬TeardownÔÚÿ¸öSepcÖ´ÐÐÍêÖ®ºó×öһЩÇåÀí²Ù×÷£¬ÕâÁ½¸öº¯ÊýÃû³ÆÀ´×ÔÓÚJUnit£©£¬ÊÇÓÉÒ»×éÈ«¾ÖbeforeEach£¬afterEach£¬
beforeAll£¬afterAllº¯ÊýÀ´ÊµÏֵġ£
?beforeEach()£ºÔÚdescribeº¯ÊýÖÐÿ¸öSpecÖ´ÐÐ֮ǰִÐС£
?afterEach()£º ÔÚdescribeº¯ÊýÖÐÿ¸öSpecÊýÖ´ÐÐÖ®ºóÖ´ÐС£
?beforeAll()£ºÔÚdescribeº¯ÊýÖÐËùÓеÄSpecsÖ´ÐÐ֮ǰִÐУ¬µ«Ö»Ö´ÐÐÒ»´Î£¬ÔÚSepcÖ®¼ä²¢²»»á±»Ö´ÐС£
?afterAll()£º ÔÚdescribeº¯ÊýÖÐËùÓеÄSpecsÖ´ÐÐÖ®ºóÖ´ÐУ¬µ«Ö»Ö´ÐÐÒ»´Î£¬ÔÚSepcÖ®¼ä²¢²»»á±»Ö´ÐС£
beforeAll ºÍ afterAllÊÊÓÃÓÚÖ´ÐбȽϺÄʱ»òÕߺÄ×ÊÔ´µÄһЩ¹²Í¬µÄ³õʼ»¯ºÍÇåÀí¹¤×÷¡£¶øÇÒÔÚʹÓÃʱ»¹Òª×¢Ò⣬ËüÃDz»»áÔÚÿ¸öSpecÖ®¼äÖ´ÐУ¬ËùÒÔ²»ÊÊÓÃÓÚÿ´ÎÖ´ÐÐǰ¶¼ÐèÒª¸É¾»»·¾³µÄSpec¡£
thisÖµ
³ýÁËÔÚdescribeº¯Êý¿ªÊ¼¶¨Òå±äÁ¿£¬ÓÃÓÚ¸÷itº¯Êý¹²ÏíÊý¾ÝÍ⣬»¹¿ÉÒÔͨ¹ýthis¹Ø¼ü×ÖÀ´¹²ÏíÊý¾Ý¡£
ÔÚÔÚÿһ¸öSpecµÄÉúÃüÖÜÆÚ£¨beforeEach->it->afterEach£©µÄ¿ªÊ¼£¬¶¼½«ÓÐÒ»¸ö¿ÕµÄthis¶ÔÏó£¨ÔÚ¿ªÊ¼ÏÂÒ»¸öSpecÖÜÆÚʱ£¬this»á±»ÖØÖÃΪ¿Õ¶ÔÏ󣩡£
ǶÌ×Suite
describeº¯Êý¿ÉÒÔǶÌ×£¬Ã¿²ã¶¼¿ÉÒÔ¶¨ÒåSpecs¡£ÕâÑù¾Í¿ÉÒÔÈÃÒ»¸öSuiteÓÉÒ»×éÊ÷×´µÄ·½·¨×é³É¡£
ÿ¸öǶÌ×µÄdescribeº¯Êý£¬¶¼¿ÉÒÔÓÐ×Ô¼ºµÄbeforeEach£¬afterEachº¯Êý¡£
ÔÚÖ´ÐÐÿ¸öÄÚ²ãSpecʱ£¬¶¼»á°´Ç¶Ì×µÄÓÉÍâ¼°ÄÚµÄ˳ÐòÖ´ÐÐÿ¸öbeforeEachº¯Êý£¬ËùÒÔÄÚ²ãSepc¿ÉÒÔ·ÃÎʵ½Íâ²ãSepcÖеÄbeforeEachÖеÄÊý¾Ý¡£ÀàËÆµÄ£¬µ±ÄÚ²ãSpecÖ´ÐÐÍê³Éºó£¬»á°´ÓÉÄÚ¼°ÍâµÄ˳ÐòÖ´ÐÐÿ¸öafterEachº¯Êý¡£
describe("A spec", function() { var foo;
beforeEach(function() {
foo = 0;
foo += 1;
});
afterEach(function() {
foo = 0;
});
it("is just a function, so it can contain
any code", function() {
expect(foo).toEqual(1);
});
it("can have more than one expectation",
function() {
expect(foo).toEqual(1);
expect(true).toEqual(true);
});
describe("nested inside a second describe",
function() {
var bar;
beforeEach(function() {
bar = 1;
});
it("can reference both scopes as needed",
function() {
expect(foo).toEqual(bar);
});
});
}); |
Specs
Spec±íʾ²âÊÔÓÃÀý£¬ÒÔit(string, function)º¯Êý·â×°£¬ËüÒ²°üº¬2¸ö²ÎÊý£º
string£º²âÊÔÓÃÀýÃû³Æ£¬
function£º²âÊÔÓÃÀýº¯Êý¡£
Expectations
Expectation¾ÍÊÇÒ»¸ö¶ÏÑÔ£¬ÒÔexpectÓï¾ä±íʾ£¬·µ»Øtrue»òfalse¡£expectÓï¾äÓÐ1¸ö²ÎÊý£¬´ú±íÒª²âÊÔµÄʵ¼ÊÖµ£¨the
actual£©¡£
Ö»Óе±Ò»¸öSpecÖеÄËùÓÐExpectationsȫΪtureʱ£¬Õâ¸öSpec²Åͨ¹ý£¬·ñÔòʧ°Ü¡£
Expectation´øÊµ¼ÊÖµ£¬ËüºÍ±íʾƥÅ乿ÔòµÄMatcherÁ´½ÓÔÚÒ»Æð£¬Matcher´øÓÐÆÚÍûÖµ¡£
Matchers
MatcherʵÏÖÁ˶ÏÑԵıȽϲÙ×÷£¬½«Expectation´«ÈëµÄʵ¼ÊÖµºÍMatcher´«ÈëµÄÆÚÍûÖµ±È½Ï¡£
ÈκÎMatcher¶¼ÄÜͨ¹ýÔÚexpectµ÷ÓÃMatcherǰ¼ÓÉÏnotÀ´ÊµÏÖÒ»¸ö·ñ¶¨µÄ¶ÏÑÔ£¨expect(a).not().toBe(false);£©¡£
³£ÓõÄMatchersÓУº
toBe()£ºÏ൱ÓÚ===±È½Ï¡£
toNotBe()
toBeDefined()£º¼ì²é±äÁ¿»òÊôÐÔÊÇ·ñÒÑÉùÃ÷ÇÒ¸³Öµ¡£
toBeUndefined()
toBeNull()£ºÊÇ·ñÊÇnull¡£
toBeTruthy()£ºÈç¹ûת»»Îª²¼¶ûÖµ£¬ÊÇ·ñΪtrue¡£
toBeFalsy()
toBeLessThan()£ºÊýÖµ±È½Ï£¬Ð¡ÓÚ¡£
toBeGreaterThan()£ºÊýÖµ±È½Ï£¬´óÓÚ¡£
toEqual()£ºÏ൱ÓÚ==£¬×¢ÒâÓëtoBe()µÄÇø±ð¡£
Ò»¸öн¨µÄObject²»ÊÇ£¨not to be£©ÁíÒ»¸öн¨µÄObject£¬µ«ÊÇËüÃÇÊÇÏàµÈ£¨to
equal£©µÄ¡£
expect({}).not().toBe({}); expect({}).toEqual({}); |
toNotEqual()
toContain()£ºÊý×éÖÐÊÇ·ñ°üº¬ÔªËØ£¨Öµ£©¡£Ö»ÄÜÓÃÓÚÊý×飬²»ÄÜÓÃÓÚ¶ÔÏó¡£
toBeCloseTo()£ºÊýÖµ±È½Ïʱ¶¨Ò徫¶È£¬ÏÈËÄÉáÎåÈëºóÔٱȽϡ£
it("The 'toBeCloseTo' matcher is for precision math comparison", function() { var pi = 3.1415926, e = 2.78;
expect(pi).not.toBeCloseTo(e, 2);
expect(pi).toBeCloseTo(e, 0);
}); |
toHaveBeenCalled()
toHaveBeenCalledWith()
toMatch()£º°´ÕýÔò±í´ïʽƥÅä¡£
toNotMatch()
toThrow()£º¼ìÑéÒ»¸öº¯ÊýÊÇ·ñ»áÅ׳öÒ»¸ö´íÎó
×Ô¶¨ÒåMatchersµÄʵÏÖ
×Ô¶¨ÒåMatcher£¨±»³ÆÎªMatcher Factories£©ÊµÖÊÉÏÊÇÒ»¸öº¯Êý£¨¸Ãº¯ÊýµÄ²ÎÊý¿ÉÒÔΪ¿Õ£©£¬¸Ãº¯Êý·µ»ØÒ»¸ö±Õ°ü£¬¸Ã±Õ°üµÄ±¾ÖÊÊÇÒ»¸öcompareº¯Êý£¬compareº¯Êý½ÓÊÜ2¸ö²ÎÊý£ºactual
value ºÍ expected value¡£
compareº¯Êý±ØÐë·µ»ØÒ»¸ö´øpassÊôÐԵĽá¹ûObject£¬passÊôÐÔÊÇÒ»¸öBooleanÖµ£¬±íʾ¸ÃMatcherµÄ½á¹û£¨Îªtrue±íʾ¸ÃMatcherʵ¼ÊÖµÓëÔ¤ÆÚֵƥÅ䣬Ϊfalse±íʾ²»Æ¥Å䣩£¬Ò²¾ÍÊÇ˵£¬Êµ¼ÊÖµÓëÔ¤ÆÚÖµ¾ßÌåµÄ±È½Ï²Ù×÷µÄ½á¹û£¬´æ·ÅÓÚpassÊôÐÔÖС£
×îºó²âÊÔÊä³öµÄʧ°ÜÐÅÏ¢Ó¦¸ÃÔÚ·µ»Ø½á¹ûObjectÖеÄmessageÊôÐÔÖÐÀ´¶¨Òå¡£
var customMatchers = { toBeGoofy: function(util, customEqualityTesters) { return { compare: function(actual, expected) { if (expected === undefined) { expected = ''; } var result = {}; result.pass = util.equals(actual.hyuk, "gawrsh" + expected, customEqualityTesters); if (result.pass) { result.message = "Expected " + actual + " not to be quite so goofy"; } else { result.message = "Expected " + actual + " to be goofy, but it was not very goofy"; } return result; } }; } }; |
×Ô¶¨ÒåMatchersµÄʹÓÃ
¶Ô×Ô¶¨ÒåMatcherÓÐ2ÖÖʹÓ÷½·¨£º
½«¸Ãº¯ÊýÌí¼Óµ½Ò»¸öÌØ¶¨µÄdescribeº¯ÊýµÄbeforeEachÖУ¬ÒÔ±ã¸Ãdescribeº¯ÊýÖеÄËùÓÐSpec¶¼Äܵ÷Óõ½Ëü¡£µ«ÆäËûdescribeÖв¢²»ÄÜʹÓøÃMatcher¡£
¸Ã·½·¨µÄÀý×Ó¿ÉÒԲο¼¹ÙÍøÌṩµÄcustom_matcher.jsµÄʵÏÖ[3]¡£
describe("Custom matcher: 'toBeGoofy'", function() { beforeEach(function() { jasmine.addMatchers(customMatchers); });
it("can take an 'expected'
parameter", function() {
expect({
hyuk: 'gawrsh is fun'
}).toBeGoofy(' is fun');
});
}); |
½«¸Ãº¯ÊýÌí¼Óµ½È«¾ÖµÄbeforeEachº¯ÊýÖУ¬ÕâÑùËùÓеÄSuitesÖеÄËùÓеÄSpecs£¬¶¼¿ÉÒÔʹÓøÃMatcher¡£
¸Ã·½·¨µÄÀý×Ó¿ÉÒԲο¼JasmineÌṩµÄDemoÖеÄSpecHelper.jsÎļþÖеÄtoBePlaying×Ô¶¨ÒåµÄ¹æÔòµÄʵÏÖ¡£
//¶¨Òå beforeEach(function () { jasmine.addMatchers({ toBePlaying: function () { // ×Ô¶¨ÒåMatcher£ºtoBePlaying return { //Òª·µ»ØµÄcompareº¯Êý compare: function (actual, expected) { var player = actual; //compareº¯ÊýÖÐÒª·µ»ØµÄ½á¹ûObject£¬ÕâÀïÊÇÒ»¸öÄäÃûObject£¬°üº¬Ò»¸öpassÊôÐÔ¡£ return { pass: player.currentlyPlayingSong === expected && player.isPlaying } } }; } }); }); //ʹÓà describe("Player", function() { it("should be able to play a Song", function() { player.play(song); //demonstrates use of custom matcher expect(player).toBePlaying(song); });
describe("when song has been paused",
function() {
it("should indicate that the song is currently
paused", function() {
// demonstrates use of 'not' with a custom matcher
expect(player).not.toBePlaying(song);
});
)}; |
½ûÓÃSuites
Suites¿ÉÒÔ±»Disabled¡£ÔÚdescribeº¯ÊýÃû֮ǰÌí¼Óx¼´¿É½«Suite½ûÓá£
±»DisabledµÄSuitesÔÚÖ´ÐÐÖÐ»á±»Ìø¹ý£¬¸ÃSuiteµÄ½á¹ûÒ²²»»áÏÔʾÔÚ½á¹û¼¯ÖС£
xdescribe("A spec", function() { var foo;
beforeEach(function() {
foo = 0;
foo += 1;
});
it("is just a function, so it can contain
any code", function() {
expect(foo).toEqual(1);
});
}); |
¹ÒÆðSpecs
ÓÐ3ÖÖ·½·¨¿ÉÒÔ½«Ò»¸öSpec±ê¼ÇΪPending¡£±»PendingµÄSpec²»»á±»Ö´ÐУ¬µ«ÊÇSpecµÄÃû×Ö»áÔÚ½á¹û¼¯ÖÐÏÔʾ£¬Ö»ÊDZê¼ÇΪPending¡£
Èç¹ûÔÚSpecº¯ÊýitµÄº¯ÊýÃû֮ǰÌí¼Óx£¨xit£©£¬ÄÇô¸ÃSpec¾Í»á±»±ê¼ÇΪPending¡£
Ò»¸öûÓж¨Ò庯ÊýÌåµÄSepcÒ²»áÔÚ½á¹û¼¯Öб»±ê¼ÇΪPending¡£
Èç¹ûÔÚSpecµÄº¯ÊýÌåÖе÷ÓÃpending()º¯Êý£¬ÄÇô¸ÃSpecÒ²»á±»±ê¼ÇΪPending¡£pending()º¯Êý½ÓÊÜÒ»¸ö×Ö·û´®²ÎÊý£¬¸Ã²ÎÊý»áÔÚ½á¹û¼¯ÖÐÏÔʾÔÚPENDING
WITH MESSAGE:Ö®ºó£¬×÷ΪΪºÎ±»PendingµÄÔÒò¡£
describe("Pending specs", function() {
xit("can be declared 'xit'", function()
{
expect(true).toBe(false);
});
it("can be declared with 'it' but without
a function");
it("can be declared by calling 'pending'
in the spec body", function() {
expect(true).toBe(false);
pending('this is why it is pending');
});
}); |
¸ß¼¶ÌØÐÔ
Spy
SpyÄܼà²âÈκÎfunctionµÄµ÷Óúͷ½·¨²ÎÊýµÄµ÷Óúۼ£¡£ÐèʹÓÃ2¸öÌØÊâµÄMatcher£º
toHaveBeenCalled£º¿ÉÒÔ¼ì²éfunctionÊÇ·ñ±»µ÷Óùý£¬
toHaveBeenCalledWith£º ¿ÉÒÔ¼ì²é´«Èë²ÎÊýÊÇ·ñ±»×÷Ϊ²ÎÊýµ÷Óùý¡£
spyOn
ʹÓÃspyOn(obj,'function')À´ÎªobjµÄfunction·½·¨ÉùÃ÷Ò»¸öSpy¡£²»¹ýҪעÒâµÄÒ»µãÊÇ£¬¶ÔSpyº¯ÊýµÄµ÷Óò¢²»»áÓ°ÏìÕæÊµµÄÖµ¡£
describe("A spy", function() { var foo, bar = null;
beforeEach(function() {
foo = {
setBar: function(value) {
bar = value;
}
};
spyOn(foo, 'setBar');
foo.setBar(123);
foo.setBar(456, 'another param');
});
it("tracks that the spy was called",
function() {
expect(foo.setBar).toHaveBeenCalled();
});
it("tracks all the arguments of its calls",
function() {
expect(foo.setBar).toHaveBeenCalledWith(123);
expect(foo.setBar).toHaveBeenCalledWith(456, 'another
param');
});
it("stops all execution on a function",
function() {
// SpyµÄµ÷Óò¢²»»áÓ°ÏìÕæÊµµÄÖµ£¬ËùÒÔbarÈÔÈ»ÊÇnull¡£
expect(bar).toBeNull();
});
}); |
and.callThrough
Èç¹ûÔÚspyOnÖ®ºóÁ´Ê½µ÷ÓÃand.callThrough£¬ÄÇôSpy³ýÁ˸ú×ÙËùÓеĺ¯Êýµ÷ÓÃÍ⣬»¹»áÖ±½Óµ÷Óú¯Êý¶îÕæÊµÊµÏÖ£¬Òò´ËSpy·µ»ØµÄÖµ¾ÍÊǺ¯Êýµ÷Óúóʵ¼ÊµÄÖµÁË¡£
... spyOn(foo, 'getBar').and.callThrough(); foo.setBar(123); fetchedBar = foo.getBar();
it("tracks that the spy was called",
function() {
expect(foo.getBar).toHaveBeenCalled();
});
it("should not effect other functions",
function() {
expect(bar).toEqual(123);
});
it("when called returns the requested value",
function() {
expect(fetchedBar).toEqual(123);
});
}); |
and.stub
ÔÚµ÷ÓÃand.callThroughºó£¬Èç¹ûÄãÏë×èÖ¹spi¼ÌÐø¶Ôʵ¼ÊÖµ²úÉúÓ°Ï죬Äã¿ÉÒÔµ÷ÓÃand.stub¡£Ò²¾ÍÊÇ˵£¬and.stubÊǽ«spi¶Ôʵ¼ÊʵÏÖµÄÓ°Ï컹Ե½×îÖÕµÄ״̬¡ª¡ª²»Ó°Ïìʵ¼ÊÖµ¡£
spyOn(foo, 'setBar').and.callThrough();
foo.setBar(123);
// ʵ¼ÊµÄbar=123
expect(bar).toEqual(123);
// µ÷ÓÃand.stub()ºó£¬Ö®ºóµ÷ÓÃfoo.setBar½«²»»áÓ°ÏìbarµÄÖµ¡£
foo.setBar.and.stub();
foo.setBar(456);
expect(bar).toBe(123);
bar = null;
foo.setBar(123);
expect(bar).toBe(null); |
È«¾ÖÆ¥Åäν´Ê
jasmine.any
jasmine.anyµÄ²ÎÊýΪһ¸ö¹¹Ô캯Êý£¬ÓÃÓÚ¼ì²â¸Ã²ÎÊýÊÇ·ñÓëʵ¼ÊÖµËù¶ÔÓ¦µÄ¹¹Ô캯ÊýÏàÆ¥Åä¡£
describe("jasmine.any", function() { it("matches any value", function() { expect({}).toEqual(jasmine.any(Object)); expect(12).toEqual(jasmine.any(Number)); });
describe("when used with a spy", function()
{
it("is useful for comparing arguments",
function() {
var foo = jasmine.createSpy('foo');
foo(12, function() {
return true;
});
expect(foo).toHaveBeenCalledWith(jasmine.any(Number),
jasmine.any(Function));
});
});
}); |
jasmine.anything
jasmine.anythingÓÃÓÚ¼ì²âʵ¼ÊÖµÊÇ·ñΪnull»òundefined£¬Èç¹û²»Îªnull»òundefined£¬Ôò·µ»Øtrue¡£
it("matches anything", function() { expect(1).toEqual(jasmine.anything()); }); |
jasmine.objectContaining
ÓÃÓÚ¼ì²âʵ¼ÊObjectÖµÖÐÊÇ·ñ´æÔÚÌØ¶¨key/value¶Ô¡£
var foo;
beforeEach(function() {
foo = {
a: 1,
b: 2,
bar: "baz"
};
});
it("matches objects with the expect key/value
pairs", function() {
expect(foo).toEqual(jasmine.objectContaining({
bar: "baz"
}));
expect(foo).not.toEqual(jasmine.objectContaining({
c: 37
}));
}); |
jasmine.arrayContaining
ÓÃÓÚ¼ì²âʵ¼ÊArrayÖµÖÐÊÇ·ñ´æÔÚÌØ¶¨Öµ¡£
var foo;
beforeEach(function() {
foo = [1, 2, 3, 4];
});
it("matches arrays with some of the values",
function() {
expect(foo).toEqual(jasmine.arrayContaining([3,
1]));
expect(foo).not.toEqual(jasmine.arrayContaining([6]));
}); |
Jasmine Clock
Jasmine ClockÓÃÓÚsetTimeoutºÍsetIntervalµÄ»Øµ÷¿ØÖÆ£¬ËüʹtimerµÄ»Øµ÷º¯Êýͬ²½»¯£¬²»ÔÙÒÀÀµÓÚ¾ßÌåµÄʱ¼ä£¬¶øÊǽ«Ê±¼äÀëÉ¢»¯£¬Ê¹²âÊÔÈËÔ±Äܾ«È·¿ØÖƾßÌåµÄʱ¼äµã¡£
°²×°ÓëÐ¶ÔØ
µ÷ÓÃjasmine.clock().install()¿ÉÒÔÔÚÌØ¶¨µÄÐèÒª²Ù×Ýʱ¼äµÄSpec»òÕßSuiteÖа²×°Jasmine
Clock£¬×¢Òâ²Ù×÷ÍêºóÒªµ÷ÓÃjasmine.clock().uninstall()½øÐÐÐ¶ÔØ¡£
var timerCallback; beforeEach(function() { timerCallback = jasmine.createSpy("timerCallback"); jasmine.clock().install(); }); afterEach(function() { jasmine.clock().uninstall(); }); |
Ä£Äⳬʱ£¨Mocking Timeout£©
¿ÉÒÔµ÷ÓÃjasmine.clock().tick(nTime)À´Ä£Äâ¼ÆÊ±£¬Ò»µ©tickÖÐÉèÖõÄʱ¼änTime£¬ÆäÀÛ¼ÆÉèÖõÄÖµ´ïµ½setTimeout»òsetIntervalÖÐÖ¸¶¨µÄÑÓʱʱ¼ä£¬Ôò´¥·¢»Øµ÷º¯Êý¡£
it("causes an interval to be called synchronously", function() { setInterval(function() { timerCallback(); }, 100);
expect(timerCallback).not.toHaveBeenCalled();
jasmine.clock().tick(101);
expect(timerCallback.calls.count()).toEqual(1);
jasmine.clock().tick(50);
expect(timerCallback.calls.count()).toEqual(1);
//tickÉèÖõÄʱ¼ä£¬ÀۼƵ½´Ë201ms£¬Òò´Ë»á´¥·¢setIntervalÖеĻٵôº¯Êý±»µ÷ÓÃ2´Î¡£
jasmine.clock().tick(50);
expect(timerCallback.calls.count()).toEqual(2);
}); |
Òì²½Ö§³Ö£¨Asynchronous Support£©
µ÷ÓÃbeforeEach£¬it»òÕßafterEachʱ£¬¿ÉÒÔÌí¼ÓÒ»¸ö¿ÉÑ¡²ÎÊý£¨FunctionÀàÐÍ£¬ÔÚ¹Ù·½ÎĵµµÄÀý×ÓÖиòÎÊýΪdone£©¡£µ±doneº¯Êý±»µ÷Ó㬱íÃ÷Òì²½²Ù×÷µÄ»Øµ÷º¯Êýµ÷Óóɹ¦£»·ñÔòÈç¹ûûÓе÷ÓÃdone£¬±íÃ÷Òì²½²Ù×÷µÄ»Øµ÷º¯Êýµ÷ÓÃʧ°Ü£¬Ôò¸ÃSpec²»»á±»µ÷Óã¬ÇÒ»áÒòΪ³¬Ê±Í˳ö¡£
JasmineµÈ´ýÒì²½²Ù×÷Íê³ÉµÄĬÈÏʱ¼äÊÇ5s£¬Èç¹û5sÄÚÒì²½²Ù×÷ûÓÐÍê³É£¬ÔòSpec»áÒòΪ³¬Ê±Í˳ö¡£³¬Ê±Ê±¼äÒ²¿ÉÒÔͨ¹ýÈ«¾ÖµÄjasmine.DEFAULT_TIMEOUT_INTERVALÐÞ¸Ä[4]¡£
var value;
// setTimeout´ú±íÒ»¸öÒì²½²Ù×÷¡£
beforeEach(function(done) {
setTimeout(function() {
value = 0;
// µ÷ÓÃdone±íʾ»Øµ÷³É¹¦£¬·ñÔò³¬Ê±¡£
done();
}, 1);
});
// Èç¹ûÔÚbeforeEachÖеÄsetTimeoutµÄ»Øµ÷ÖÐûÓе÷ÓÃdone£¬×îÖÕµ¼ÖÂÏÂÃæµÄitÒò³¬Ê±¶øÊ§°Ü¡£
it("should support async execution of test
preparation and expectations", function(done)
{
value++;
expect(value).toBeGreaterThan(0);
done();
}); |
|