Closed thislooksfun closed 8 years ago
Hey, sorry I missed this issue.
In this particular example, the mockDir.restore()
API would not be possible due to mockDir being a string. There are some tricks we can pull, but I prefer to keep it as clean as possible. The only other option is to not return the mocked value, but to return the reference to the mock. This would be a problem for chaining on function mocks, so we'd have to return something different for value mocks vs function mocks. This would work, but it could be a breaking change for some, which could be painful, however rare this may be. Do you have any ideas on how you'd want to implement it?
I usually try to keep shared setup for subsequent tests in something such as a beforeEach
block or just a setup function.
So, correct me if I'm wrong: the problem is that currently the simple.mock
function returns the object that is being replaced, and you (understandably) don't want to change that because it would break existing setups?
Correct. This behaviour enables you to chain behaviour instructions, e.g.
simple.mock(object, 'key')
.returnWith('something')
.throwWith(new Error('already returned')`
I do realise that the case for simple value substitution, i.e. not a method mock, does not benefit from chaining anyway. Would an API such as simple.restore(object, 'key')
be good?
That method could work, but I'm worried about multiple mocks replacing the same value.
I've been playing around a bit, but so far I have been unable to come up with a good way to keep the string and still add a restore function, but I believe the chaining problem can be easily solved by adding the restore
function to the mock. It doesn't have to be chainable itself, because why would you want to call something else after it, but it can go somewhere in here
My work so far:
var str = "hi";
var strWithRestore = Object(str);
strWithRestore.restoreMock = function() {
return console.log("Hello!");
};
var testing = {
hi: "1",
hello: "2"
};
testing[str]; // Gives '1'
testing[strWithRestore]; // Still gives '1'
typeof strWithRestore == "string" // Doesn't work, returns 'object'
That's perhaps a bit too clever, changing to a string object.
I've implemented the simple.restore(object, 'key')
method in the above commit. This should not break any existing APIs and is even safe if you mock a value multiple times - it will only restore the last mocked value.
Awesome, thanks! My confusion about conflicting mocks was that I, for whatever silly reason, thought you meant to implement it like so:
mockDir = simple.mock(object, "key", "new information")
do_something()
simple.restore(mockDir)
Which would fail if mockDir
was the same string as any other mock. I now understand what you actually meant by that, and I have to say, that's a very nice solution.
Hello! First off, I love this tool. I took one look at sinon and instantly sought a more intuitive method, and I wound up finding this! I only have one request, which is a
restore()
function on individual mocks. In my tests I'm finding myself needing to mocks for one method call that need to be undone before the next one, and I would like a way to not have to redo all the other mocks and spies.Proposed format: