如何使用Jasmine测试该JavaScript Service模块的doStuff方法?
用Jasmine测试你的Service模块
没问题,我来帮你一步步实现这段代码的Jasmine测试。针对你的doStuff函数,我们需要覆盖所有分支场景,同时验证对应函数是否被正确调用。
测试思路
我们需要测试以下几个核心场景:
- 传入
command: "A"时,调用a函数并返回其结果 - 传入
command: "B"时,调用b函数并返回其结果 - 传入
command: "C"时,调用c函数并返回其结果 - 传入未定义的command时,返回默认值
"NOPE!"
为了不依赖a/b/c函数的内部实现,我们可以用Jasmine的**间谍(spy)**来模拟这些函数的返回值,并验证它们是否被正确调用。
具体测试代码
假设你的Service模块最终完整返回如下(暴露内部函数方便测试):
var Service = (function() { function doStuff(command, package) { var response = "" switch(command) { case "A": response = a(package); break; case "B": response = b(package); break; case "C": response = c(package); break; default: response = "NOPE!"; } return response; } function a(package) { return "resultA"; } function b(package) { return "resultB"; } function c(package) { return "resultC"; } return { doStuff: doStuff, a: a, b: b, c: c }; })();
对应的Jasmine测试代码如下:
describe("Service", function() { // 在每个测试前重置间谍,避免测试间相互影响 beforeEach(function() { // 为a/b/c函数创建间谍,保留原始实现(或用and.returnValue模拟返回) spyOn(Service, 'a').and.callThrough(); spyOn(Service, 'b').and.callThrough(); spyOn(Service, 'c').and.callThrough(); }); it("should call function 'a' and return its result when command is 'A'", function() { const testPackage = { data: "test" }; const result = Service.doStuff("A", testPackage); // 验证a函数被调用了一次,且传入了正确的参数 expect(Service.a).toHaveBeenCalledTimes(1); expect(Service.a).toHaveBeenCalledWith(testPackage); // 验证返回值正确 expect(result).toBe("resultA"); }); it("should call function 'b' and return its result when command is 'B'", function() { const testPackage = { data: "testB" }; const result = Service.doStuff("B", testPackage); expect(Service.b).toHaveBeenCalledTimes(1); expect(Service.b).toHaveBeenCalledWith(testPackage); expect(result).toBe("resultB"); }); it("should call function 'c' and return its result when command is 'C'", function() { const testPackage = { data: "testC" }; const result = Service.doStuff("C", testPackage); expect(Service.c).toHaveBeenCalledTimes(1); expect(Service.c).toHaveBeenCalledWith(testPackage); expect(result).toBe("resultC"); }); it("should return 'NOPE!' when command is not recognized", function() { const result = Service.doStuff("D", {}); // 验证a/b/c都没有被调用 expect(Service.a).not.toHaveBeenCalled(); expect(Service.b).not.toHaveBeenCalled(); expect(Service.c).not.toHaveBeenCalled(); // 验证默认返回值 expect(result).toBe("NOPE!"); }); });
关键测试点说明
- 间谍的使用:
spyOn(Service, 'a').and.callThrough()会监视Service.a函数,同时保留它的原始实现;如果你不想依赖原始函数的返回值,可以用and.returnValue("customResult")来模拟返回,比如spyOn(Service, 'a').and.returnValue("mockA"),这样测试更独立。 - 参数验证:
toHaveBeenCalledWith(testPackage)确保函数被传入了正确的参数,避免逻辑出错。 - 分支覆盖:我们覆盖了switch的所有case和default分支,确保代码的每个路径都被测试到。
如果你的a/b/c是私有函数(没有暴露在返回对象里),那需要稍微调整代码结构,比如把这些函数作为Service的内部属性,或者用Jasmine的spyOn配合闭包的方式来监视,不过更推荐的是将需要测试的依赖暴露出来,或者重构代码让逻辑更易测试。
内容的提问来源于stack exchange,提问作者Drew S.
相关产品推荐
相关产品推荐

