Skip to content

Instantly share code, notes, and snippets.

@loilo
Last active January 21, 2020 10:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save loilo/696a451dfff3cbf6acdd8bae56235831 to your computer and use it in GitHub Desktop.
Save loilo/696a451dfff3cbf6acdd8bae56235831 to your computer and use it in GitHub Desktop.
Moxy – a function that mocks an object's properties and methods with a proxy

Moxy

Moxy is a function that mocks an object with a proxy by shadowing its properties and methods. This can be vastly useful for testing, when there are properties which are not writable or which you don't want to override to avoid side effects.

This is best explained with the example where moxy origins: Vue's $isServer property. It defaults to false and is not configurable, therefore it can not be overridden. However, I needed that property to be true.

I solved this with moxy by replacing a Vue instance's prototype with a proxy of itself that returns true when asked for $isServer:

const vm = new Vue()

console.assert(vm.$isServer === false) // 🤨

const originalPrototype = Object.getPrototypeOf(vm)
const mockedPrototype = moxy(originalPrototype, { $isServer: true })
Object.setPrototypeOf(vm, mockedPrototype)

console.assert(vm.$isServer === true) // 🎉
/**
* Mock an object with a proxy, overriding methods and properties
*
* @param {object} object An object to mock
* @param {object} implementations The properties/methods to virtually "merge" into the mocked object
*/
function moxy(object, implementations) {
return new Proxy(object, {
get(target, key, receiver) {
if (key in implementations) {
const result = implementations[key]
if (typeof result === 'function') {
return result.bind(object)
} else {
return result
}
} else {
return Reflect.get(target, key, receiver)
}
}
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment