Skip to content

Commit 278c2ce

Browse files
committed
Add getters/setters stub behaviors
1 parent e0cfccc commit 278c2ce

3 files changed

Lines changed: 120 additions & 23 deletions

File tree

lib/sinon/default-behaviors.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,26 @@ module.exports = {
163163

164164
callThrough: function callThrough(fake) {
165165
fake.callsThrough = true;
166+
},
167+
168+
get: function get(fake, getterFunction) {
169+
var rootStub = fake.stub || fake;
170+
171+
Object.defineProperty(rootStub.rootObj, rootStub.propName, {
172+
get: getterFunction
173+
});
174+
175+
return fake;
176+
},
177+
178+
set: function set(fake, setterFunction) {
179+
var rootStub = fake.stub || fake;
180+
181+
Object.defineProperty(rootStub.rootObj, rootStub.propName, { // eslint-disable-line accessor-pairs
182+
set: setterFunction
183+
});
184+
185+
return fake;
166186
}
167187
};
168188

lib/sinon/stub.js

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ var behaviors = require("./default-behaviors");
55
var spy = require("./spy");
66
var extend = require("./util/core/extend");
77
var functionToString = require("./util/core/function-to-string");
8+
var getPropertyDescriptor = require("./util/core/get-property-descriptor");
89
var wrapMethod = require("./util/core/wrap-method");
910
var stubEntireObject = require("./stub-entire-object");
1011
var stubDescriptor = require("./stub-descriptor");
@@ -13,24 +14,38 @@ var throwOnFalsyObject = require("./throw-on-falsy-object");
1314
function stub(object, property, descriptor) {
1415
throwOnFalsyObject.apply(null, arguments);
1516

17+
var actualDescriptor = getPropertyDescriptor(object, property);
1618
var isStubbingEntireObject = typeof property === "undefined" && typeof object === "object";
1719
var isCreatingNewStub = !object && typeof property === "undefined";
1820
var isStubbingDescriptor = object && property && Boolean(descriptor);
21+
var isStubbingNonFuncProperty = typeof object === "object"
22+
&& typeof property !== "undefined"
23+
&& (typeof actualDescriptor === "undefined"
24+
|| typeof actualDescriptor.value !== "function")
25+
&& typeof descriptor === "undefined";
1926
var isStubbingExistingMethod = !isStubbingDescriptor
2027
&& typeof object === "object"
21-
&& typeof object[property] === "function";
28+
&& typeof actualDescriptor !== "undefined"
29+
&& typeof actualDescriptor.value === "function";
2230
var arity = isStubbingExistingMethod ? object[property].length : 0;
2331

2432
if (isStubbingEntireObject) {
2533
return stubEntireObject(stub, object);
2634
}
2735

36+
if (isStubbingDescriptor) {
37+
return stubDescriptor.apply(null, arguments);
38+
}
39+
2840
if (isCreatingNewStub) {
2941
return stub.create();
3042
}
3143

32-
if (isStubbingDescriptor) {
33-
return stubDescriptor.apply(null, arguments);
44+
if (isStubbingNonFuncProperty) {
45+
var s = stub.create();
46+
s.rootObj = object;
47+
s.propName = property;
48+
return s;
3449
}
3550

3651
return wrapMethod(object, property, stub.create(arity));

test/stub-test.js

Lines changed: 82 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -800,16 +800,6 @@ describe("stub", function () {
800800
assert.isFalse(stub.called);
801801
});
802802

803-
it("throws if property is not a function", function () {
804-
var obj = { someProp: 42 };
805-
806-
assert.exception(function () {
807-
createStub(obj, "someProp");
808-
});
809-
810-
assert.equals(obj.someProp, 42);
811-
});
812-
813803
it("successfully stubs falsey properties", function () {
814804
var obj = { 0: function () { } };
815805

@@ -943,16 +933,6 @@ describe("stub", function () {
943933
});
944934

945935
describe("stubbed function", function () {
946-
it("throws if stubbing non-existent property", function () {
947-
var myObj = {};
948-
949-
assert.exception(function () {
950-
createStub(myObj, "ouch");
951-
});
952-
953-
refute.defined(myObj.ouch);
954-
});
955-
956936
it("has toString method", function () {
957937
var obj = { meth: function () {} };
958938
createStub(obj, "meth");
@@ -2301,4 +2281,86 @@ describe("stub", function () {
23012281
assert.equals(reference, myObj);
23022282
});
23032283
});
2284+
2285+
describe(".get", function () {
2286+
it("allows users to stub getter functions for properties", function () {
2287+
var myObj = {
2288+
prop: "foo"
2289+
};
2290+
2291+
createStub(myObj, "prop").get(function () {
2292+
return "bar";
2293+
});
2294+
2295+
assert.equals(myObj.prop, "bar");
2296+
});
2297+
2298+
it("replaces old getters", function () {
2299+
var myObj = {
2300+
get prop() {
2301+
fail("should not call the old getter");
2302+
}
2303+
};
2304+
2305+
createStub(myObj, "prop").get(function () {
2306+
return "bar";
2307+
});
2308+
2309+
assert.equals(myObj.prop, "bar");
2310+
});
2311+
2312+
it("can set getters for non-existing properties", function () {
2313+
var myObj = {};
2314+
2315+
createStub(myObj, "prop").get(function () {
2316+
return "bar";
2317+
});
2318+
2319+
assert.equals(myObj.prop, "bar");
2320+
});
2321+
});
2322+
2323+
describe(".set", function () {
2324+
it("allows users to stub setter functions for properties", function () {
2325+
var myObj = {
2326+
prop: "foo"
2327+
};
2328+
2329+
createStub(myObj, "prop").set(function () {
2330+
myObj.example = "bar";
2331+
});
2332+
2333+
myObj.prop = "baz";
2334+
2335+
assert.equals(myObj.example, "bar");
2336+
});
2337+
2338+
it("replaces old setters", function () {
2339+
var myObj = { // eslint-disable-line accessor-pairs
2340+
set prop(val) {
2341+
fail("should not call the old setter");
2342+
}
2343+
};
2344+
2345+
createStub(myObj, "prop").set(function () {
2346+
myObj.example = "bar";
2347+
});
2348+
2349+
myObj.prop = "foo";
2350+
2351+
assert.equals(myObj.example, "bar");
2352+
});
2353+
2354+
it("can set setters for non-existing properties", function () {
2355+
var myObj = {};
2356+
2357+
createStub(myObj, "prop").set(function () {
2358+
myObj.example = "bar";
2359+
});
2360+
2361+
myObj.prop = "foo";
2362+
2363+
assert.equals(myObj.example, "bar");
2364+
});
2365+
});
23042366
});

0 commit comments

Comments
 (0)