Explicitly supplies the mock object that the module system should return for the specified module. Mock frameworks allow us to create mock objects at runtime and define their . Creates a new deeply cloned object. If those tasks themselves schedule new tasks, those will be continually exhausted until there are no more tasks remaining in the queue. In other cases (such as legacy timers) it may be useful for implementing custom mocks of Date.now(), performance.now(), etc. Indicates that the module system should never return a mocked version of the specified module from require() (e.g. Fix the code so any failed tests pass or write a newer, better implementation. Coreless Stretch Film; Pre-Stretch Film; Hand Roll; Machine Roll; Jumbo Roll; Industrial Plastic Division. Function mock using jest.fn () The simplest and most common way of creating a mock is jest.fn () method. Jest also provides mock function methods for resetting and restoring mocked functions, as well as shorthands for creating mocked functions that directly return, resolve, or reject a value. // creates a new class with the same interface, member functions and properties are mocked. i18next instance. Browse other questions tagged, Where developers & technologists share private knowledge with coworkers, Reach developers & technologists worldwide. and has some hardcoded data. It can also be imported explicitly by via import {jest} from '@jest/globals'. Set the current system time used by fake timers. When this API is called, all pending macro-tasks and micro-tasks will be executed. Tengo dos acotaciones: 2 El ejemplo para Mock y Automock no funcion. If no implementation is provided, calling the mock returns undefined because the return value is not defined. See automock section of configuration for more information. jest.spyOnProp (object, propertyName) Note: This is aliased as jest.spyOn as of v1.9.0, overriding the existing jest.spyOn to use spyOnProp when spying on a regular object property. Creates a mock property attached to object [propertyName] and returns a mock property spy object, which controls all access to the object property. that it should always return the real module). To set timeout intervals on different tests in the same file, use the timeout option on each individual test. Aiming to contribute to an interactive and inclusive web. By clicking Sign up for GitHub, you agree to our terms of service and This only works with computed properties. // will return 'undefined' because the function is auto-mocked. Clears the mock.calls, mock.instances, mock.contexts and mock.results properties of all mocks. You can't spy on class properties, but I don't find it useful anyway. Static ES6 module imports are hoisted to the top of the file, so instead we have to import them dynamically using, Finally, we need an environment which supports dynamic importing. Reading from the documentation, it wasn't clear how I could mock a single class instance method when it's on read-only mode. on How to mock the JavaScript window object using Jest? Full-stack generalist. latest. There are three main types of module and function mocking in Jest: Each of these will, in some way, create the Mock Function. Use this method if you want to explicitly avoid this behavior. Launching the CI/CD and R Collectives and community editing features for How do I mock an imported object in Jest? You signed in with another tab or window. // This runs the function specified as second argument to `jest.mock`. Every time Jest runs a seed value is randomly generated which you could use in a pseudorandom number generator or anywhere else. SSR (additional components) This is useful when dealing with a lot of repetition in setting up mocks such as when mocking common dependencies or configuration objects because it makes writing a mock factory function unnecessary. For further actions, you may consider blocking this person and/or reporting abuse, Check out this all-time classic DEV post on visualizing Promises and Async/Await . Step by step guide. And then we check that window.location.origin is "https://example.com". // creates a new property with the same primitive value as the original property. Writing tests in TypeScript? The new function has no formal parameters and when called will return undefined. If you found DEV from searching around, here are a couple of our most popular articles on DEV: Once suspended, dstrekelj will not be able to comment or publish posts until their suspension is removed. Returns the number of fake timers still left to run. What was your experience like? Indicates that the module system should never return a mocked version of the specified module and its dependencies. Usually Object.defineProperty works for everything, but the Location object is completely locked down from changes. If an implementation is provided, calling the mock function will call the implementation and return it's return value. Executes only the macro-tasks that are currently pending (i.e., only the tasks that have been queued by setTimeout() or setInterval() up to this point). Here's an example I wrote recently for mocking document.cookie . Clears the mock.calls, mock.instances and mock.results properties of all mocks. Returns a mock module instead of the actual module, bypassing all checks on whether the module should be required normally or not. jest mock database connection Noend Tatical Documentao para posse e porte de arma de fogo. mock. The mockImplementation() method is called with the new implementation as its argument. Equivalent to calling .mockClear() on every mocked function. There was a problem preparing your codespace, please try again. Buena serie. In the afterEach callback, we call windowSpy.mockRestore to restore window to its original state. jest.mock () is called with one required argument - the import path of the module we're mocking. // Require the original module to not be mocked // > false (Both sum modules are separate "instances" of the sum module.). A simple jest.mock call allows us to intercept any dependency of the modules we are testing, without needing to change anything in terms of implementation. Equivalent to calling .mockClear() on every mocked function. In the afterEach callback, we call windowSpy.mockRestore to restore window to its original state. Making statements based on opinion; back them up with references or personal experience. Returns a new, unused mock function. This only works with the default jest-circus runner! Returns true if test environment has been torn down. This test should pass because of the mock. @michaeljota I arrived here from Google and tripped up on your example - others will too. This is useful for scenarios such as one where the module being tested schedules a setTimeout() whose callback schedules another setTimeout() recursively (meaning the scheduling never stops). With Sinon's spy I could do something like spy(store, 'doOneThing'); but I haven't figured out how to accomplished this with Jest. In these scenarios, it's useful to be able to run forward in time by a single step at a time. Learn more. Restores all mocks back to their original value. Mock classes and objects with the power of proxies! Given the name of a module, use the automatic mocking system to generate a mocked version of the module for you. What's the difference between a power rail and a signal line? upgrading to decora light switches- why left switch has white and black wire backstabbed? Set the default timeout interval (in milliseconds) for all tests and before/after hooks in the test file. Jest allows us to write a good testing code with a simple and modern mocking system. I hope this helped to simplify your understanding of Jest mocks so you can spend more time writing tests painlessly. This ability to "spy" on function calls is why mock functions are also called spies. You can, as I said, spy on computed properties, as they are functions underneath. This is useful to isolate specific modules for every test so that local module state doesn't conflict between tests. That's because, in the actual implementation of this package, the package returns each of useAuth0, Auth0Provider, and . to call jest.spyOn to mock the get global function in the beforeEach callback. Jest Array of objects partial match with arrayContaining and objectContaining In keeping with the user example, what if we wanted to check that we have the right ids for a list (array) of users. But you can mock the returning value of it too even its a read-only property! * List of names of APIs that should not be faked. The function checks if that the size is lower than 10,000 bytes, and returns boolean. It needs more clarity, which you have now provided. // creates a new empty array, ignoring the original array. How to test for object keys and values with Jest? They do not have an effect on the code in development or production. Follow these if you don't want to use require in your tests: When using babel-jest, calls to unmock will automatically be hoisted to the top of the code block. * Use the old fake timers implementation instead of one backed by `@sinonjs/fake-timers`. Like an API call, when we dont want to use an actual system, we can write the code like: But I assume that the mocking target is not always reassignable such as File.prototype.sizeIm going to explain this problem with a function that validates an image file size. To change the mock implementation of a function with Jest we use the mockImplementation() method of the mocked function. A web developer who always writes JavaScript. Returns the number of fake timers still left to run. Cordova Thanks for keeping DEV Community safe. mockFn.mock.instances An array that contains all the object instances that have been instantiated from this mock function using new. It will become hidden in your post, but will still be visible via the comment's permalink. The Jest Object The jest object needs to be extended in every test file. Please For those use cases, you can use spyOn. Executes only the macro-tasks that are currently pending (i.e., only the tasks that have been queued by setTimeout() or setInterval() up to this point). We use mock functions to override original function behaviour with custom mock implementations. This only affects the test file from which this function is called. jest.mock ('./config', () => ( { foo: 'zed' })) or you can modify the object: import config from './config'; config.foo = 'zed' The problem with your approach is that it would only work for modules that return functions. This property is normally generated by Babel / TypeScript, but here it needs to be set manually. This functionality also applies to async functions. Optionally, you can provide steps, so it will run steps amount of next timeouts/intervals. But if you wanna do the same in your codebase you need to take into consideration that it's a dirty hack that can potentially break something else . Note: this method was previously called autoMockOn. jeff mauro hearing aid. When we talk about mocking in Jest, were typically talking about replacing dependencies with the Mock Function. // sum is a different copy of the sum module from the previous test. Something like: Take your JavaScript testing to the next level by learning the ins and outs of Jest, the top JavaScript testing library. We dont want actual ObjectIds strewn around our code. This is how genMockFromModule will mock the following data types: Creates a new mock function. Note: The default timeout interval is 5 seconds if this method is not called. Dealing with hard questions during a software developer interview, Ackermann Function without Recursion or Stack. timer count) and reinstall fake timers using the provided options: For some reason you might have to use legacy implementation of fake timers. To mock properties that are defined as getters or setters, use jest.spyOn(object, methodName, accessType) instead. Since Jest 22.1.0+, the jest.spyOn method takes an optional third argument of accessType that can be either 'get' or 'set', which proves to be useful when you want to spy on a getter or a setter, respectively. Also I started unfreezing all es6-like exports automatically. EST. To learn more, see our tips on writing great answers. To support ES module imports - where import statements have to come first in a file - Jest automatically hoists jest.mock() calls to the top of the module. Modules that are mocked with jest.mock are mocked only for the file that calls jest.mock. But, not, you can not spy on regular properties, not even with that syntax. Connect and share knowledge within a single location that is structured and easy to search. When this API is called, all pending macro-tasks and micro-tasks will be executed. I'm using MobX for our state store so I have little control over class methods: If I want to write a test for store.doAnotherThing and test that store.doOneThing gets called once, I can't do it with store.doOneThing = jest.fn() as it's a read-only property (TypeError: Cannot assign to read only property 'doOneThing' of object '#'). The simplest way to create a Mock Function instance is with jest.fn(). Testing MomentJs with Jest 2019-08-19 Andy Desmarais Testing Andy Desmarais Is a software engineer from New Hampshire, USA. When this API is called, all timers are advanced by msToRun milliseconds. to your account. By default, jest.spyOn also calls the spied method. Let's have a look at a few examples. They are readonly, so the normal jest.spyOn() fails, but they are also not getters, so the suggested jest.spyOn(object, 'method', 'get').mockReturnValue('mockedValue'); won't work here either. Unflagging dstrekelj will restore default visibility to their posts. This function is only available when using legacy fake timers implementation. TypeScript compiler throws an error for the violation and testing wont be finished successfully. Your email address will not be published. Exhausts the micro-task queue (usually interfaced in node via process.nextTick). Often that is not the case, so we will need tools to mock existing modules and functions instead. isAtLeast18() will now always return false no matter what we call it with, because the isInteger() mock is set to always return false. Runs failed tests n-times until they pass or until the max number of retries is exhausted. Were relying on the fact that the .toString method exists on strings: The issue is that its not an object, so it behaves differently. To clear mocked functions before each test with Jest we use the beforeEach() function. Additionally, if those macro-tasks schedule new macro-tasks that would be executed within the same time frame, those will be executed until there are no more macro-tasks remaining in the queue, that should be run within msToRun milliseconds. This makes our tests more predictable (deterministic) and easier to write. The interface of the original class is maintained, all of the class member functions and properties will be mocked. However, on extremely rare occasions, even a manual mock isn't suitable for your purposes and you need to build the mock yourself inside your test. Restores the original (non-mocked) value. Sometimes you only want to watch a method be called, but keep the original implementation. 'isLocalhost returns true when HOSTNAME is localhost', 'isLocalhost returns false when HOSTNAME is not localhost', * If set to `true` all timers will be advanced automatically by 20 milliseconds. Refresh the page, check Medium 's site status, or find something. // With implementation, this mock returns `true`. 'do not advance the timers and do not fake `performance`', 'uninstall fake timers for the rest of tests in the file', Static ES6 module imports are hoisted to the top of the file, so instead we have to import them dynamically using, Finally, we need an environment which supports dynamic importing. By combining expect.objectContaining and expect.arrayContaining we can do a partial match on the objects in the array: Nowhere do you mention "as [you] said" - computed properties. Your snippet simply reads property. You use them in your persistence layer, you usually want to convert a string to an ObjectId using the ObjectId() constructor. This allows you to run your test subject, then assert how the mock was called and with what arguments: This strategy is solid, but it requires that your code supports dependency injection. How to Duplicate JavaScript Object Properties in JavaScript Another Object. @leotm I'm not sure I'm following you. When using babel-jest, calls to enableAutomock will automatically be hoisted to the top of the code block. To mock the JavaScript window object using Jest, we can use the jest.spyOn method. Jest Documentation - jest.mock(moduleName, factory, options). Mocks a module with an auto-mocked version when it is being required. Primarily focused on Javascript these days, he has development experience in C# and Java. Note If those tasks themselves schedule new tasks, those will be continually exhausted until there are no more tasks remaining in the queue. Instructs Jest to restore the original implementations of the global date, performance, time and timer APIs. Its useful to testing code that uses things like Mongos ObjectId. DEV Community A constructive and inclusive social network for software developers. When using babel-jest, calls to mock will automatically be hoisted to the top of the code block. factory and options are optional. Optionally takes a mock implementation. This is useful to isolate specific modules for every test so that local module state doesn't conflict between tests. If nothing happens, download Xcode and try again. Getting started with Cordova Hybrid Apps 8 years ago Are you a web developer but fancy getting started with apps? // creates a new mocked function with no formal arguments. Normally under those circumstances you should write a manual mock that is more adequate for the module in question. Removes any pending timers from the timer system. It can also be imported explicitly by via import {jest} from '@jest/globals'. The key thing to remember about jest.spyOn is that it is just sugar for the basic jest.fn() usage. Need to write test case for search component recivenig props from layout. timers to fire; they will fire exactly as they would have done without the call to jest.setSystemTime(). Please see. jest.isolateModules(fn) goes a step further than jest.resetModules() and creates a sandbox registry for the modules that are loaded inside the callback function. One example when this is useful is when you want to mock a module differently within the same file: Using jest.doMock() with ES6 imports requires additional steps. Use the --showSeed flag to print the seed in the test report summary. // The mock factory returns a mocked function, // For this test we'll mock isInteger to return `false`, passes if value is recognised as integer and is at least 18, // For this test we'll mock isInteger to return `true`, // We expect isInteger to be called with 123, // Clear the mock so the next test starts with fresh data, // Without clearing, there would be 2 calls total at this point, // Logs "mockBar", no need for a mock factory, Testing JavaScript with Jest (3 Part Series), How to create a binary decision tree in JavaScript, 9 Projects You Can Do To Become a Frontend Master. That function, when called, will always return false. To mock a function with Jest we use the jest.fn() function. RV coach and starter batteries connect negative to chassis; how does energy from either batteries' + terminal know which battery to flow back to? mockClear() resets all information stored in mocked functions which makes it useful for cleaning up a mock's usage data between assertions or tests. It can also be called with an optional second argument - the factory function for the mock. Copyright 2023 www.appsloveworld.com. The following test fails with Property platform does not have access type get: To make things worse, you can't even do the usual trick of directly writing (process.platform = ) and restoring later because of writable: false, (The solution here is the same as above, just adding another datapoint of where this is a painpoint), (I've added this to https://github.com/magicmark/jest-how-do-i-mock-x/tree/master/src/process-globals). See TypeScript Usage chapter of Mock Functions page for documentation. Creates a new class. Additionally, if those micro-tasks themselves schedule new micro-tasks, those will be continually exhausted until there are no more micro-tasks remaining in the queue. Explicitly supplies the mock object that the module system should return for the specified module. Merge the remote changes (e.g. Every subsequent access will use the same spy. The default is `Date.now()`. Creates a new empty array, ignoring the original. What would happen if an airplane climbed beyond its preset cruise altitude that the pilot set in the pressurization system? If you are not using/don't want to use TypeScript, the same logics can be applied to JavaScript. Mock properties are "spies" that let you control the behavior of a property that is accessed indirectly by some other code. Are you sure you want to create this branch? Keep in mind that this is a global operation and will affect other tests within the same file. I forgot the existence of mockReturnValue() Where have you been!? In the example above, the mock module has a current field which is set to a mock function. This is useful when you want to create a manual mock that extends the automatic mock's behavior. Has Microsoft lowered its Windows 11 eligibility criteria? Over the last few years Ive never quite settled on a goto deployment strategy for my apps and projects. Exhausts all tasks queued by setImmediate(). Equivalent to calling .mockRestore() on every mocked function and .restore() on every replaced property. For example: A mock function that has been instantiated twice would have the following mock.instances array: const mockFn = jest.fn(); const a = new mockFn(); const b = new mockFn(); If you want to overwrite the original function, you can use jest.spyOn(object, methodName).mockImplementation(() => customImplementation) or object[methodName] = jest.fn(() => customImplementation); Since jest.spyOn is a mock, you could restore the initial state by calling jest.restoreAllMocks in the body of the callback passed to the afterEach hook. This only works with jest-circus! The jest object is automatically in scope within every test file. With this and Jest Expect, its easy to test the captured calls: and we can change the return value, implementation, or promise resolution: Now that we covered what the Mock Function is, and what you can do with it, lets go into ways to use it. Advances all timers by the needed milliseconds so that only the next timeouts/intervals will run. The import path of the mocked module must match the import path that is present in the module we're testing. jest.isolateModules(fn) goes a step further than jest.resetModules() and creates a sandbox registry for the modules that are loaded inside the callback function. Optionally takes a mock implementation. #dokku, How Object.defineProperty saved our bacon, A tiny case study about migrating to Netlify when disaster strikes at GitHub, featuring Cloudflare, Simple, but not too simple: how using Zeits `micro` improves your Node applications, When to use Jest snapshot tests: comprehensive use-cases and examples , Bring Redux to your queue logic: an Express setup with ES6 and bull queue. Will fire exactly as they would have done without the call to jest.setSystemTime ( ) e.g! To explicitly avoid this behavior object instances that have been instantiated from mock. Property that is not the case, so it will become hidden in your post, but here needs... The interface of the specified module and its dependencies Tatical Documentao para posse e de! Object, methodName, accessType ) instead under those circumstances you should write manual. 'S useful to be able to run can, as they would have done the! Module for you value is not defined of retries is exhausted s an example I wrote recently for document.cookie. Any failed tests n-times until they pass or until the max number of fake timers still to... Conflict between tests power rail and a signal line using/don & # x27 t... Structured and easy to search with implementation, this mock returns ` true `,! Failed tests n-times until they pass or write a good testing code that things! To JavaScript understanding of Jest mocks so you can mock the JavaScript window object Jest... With custom mock implementations good testing code with a simple and modern mocking system to generate mocked... Create mock objects at runtime and define their making statements based on opinion ; back them up with or. Uses things like Mongos ObjectId anywhere else note if those tasks themselves schedule new tasks, those be. When it is being required mock object that the module system should return the... The object instances that have been instantiated from this mock returns undefined because the function is only available using... ; they will fire exactly as they are functions underneath ) constructor getting started with apps a! You sure you want to explicitly avoid this behavior useful to isolate specific modules for every file., were typically talking about replacing dependencies with the new function has no formal.! Method be called with the power of proxies actual module, bypassing all checks on the... Allow us to write test case for search component recivenig props from layout wrote recently mocking... Timers implementation a string to an ObjectId using the ObjectId ( ) usage database connection Noend Tatical Documentao para e... On computed properties timeouts/intervals will run value is not called coworkers, Reach developers & worldwide. Apps and projects dos acotaciones: 2 El ejemplo para mock jest mock object property Automock funcion! The comment 's permalink testing MomentJs with Jest we use mock functions override... Climbed beyond its preset cruise altitude that the size is lower than 10,000 bytes, and returns.. The power of proxies here from Google and tripped up on your example - others will too properties will executed. `` https: //example.com '' extends the automatic mocking system also calls the spied method old. Sometimes you only want to convert a string to an ObjectId using the ObjectId ( ) method of specified. The afterEach callback, we call windowSpy.mockRestore to restore the original class is,! The basic jest.fn ( ) method that should not be faked but still... Will become hidden in your persistence layer, you can use the jest.spyOn method ;! Sinonjs/Fake-Timers ` works with computed properties, as I said, spy on computed properties file from this... Jest.Mock ( ) method is called, will always return false argument - the import path of the module. Scenarios, it 's on read-only mode no more tasks remaining in the queue whether the we... Set in the module should be required normally or not exhausted until there are no more tasks in... Of mock functions to override original function behaviour with custom mock implementations private knowledge with coworkers, Reach developers technologists!: 2 El ejemplo para mock y Automock no funcion use jest.spyOn (,! Test environment has been torn down to decora light switches- why left switch white... ( e.g is exhausted array that contains all the object instances that have been instantiated from this returns. Collectives and community editing features for how do I mock an imported object in Jest above, the same value! The new function has no formal parameters and when called, all timers by the needed milliseconds that. Implementation, this mock function instance is with jest.fn ( ) Where have you been! jest/globals #! And define their the default timeout interval ( in milliseconds ) for tests! Explicitly supplies the mock function calls is why mock functions page for documentation code in or. Path that is more adequate for the file that calls jest.mock of service and this works. Tests within the same interface, member functions and properties will be executed Medium & x27! Still be visible via the comment 's permalink for the basic jest.fn ( ) every... To run last few years Ive never quite settled on a goto deployment strategy my! Sure you want to use TypeScript, the mock returns undefined because the return value all mocks in., performance, time and timer APIs global operation and will affect tests. Your persistence layer, you usually jest mock object property to convert a string to an ObjectId using the ObjectId ). ) ( e.g based on opinion ; back them up with references or personal experience module state does n't between. On JavaScript these days, he has development experience in C # and.... List of names of APIs that should not be faked existence of mockReturnValue ( ) on every property. Timers implementation instead of the actual module, use the automatic mocking system El ejemplo mock... Function for the specified module from require ( ) constructor tests jest mock object property predictable ( deterministic ) easier! Github, you can, as they would have done without the call to jest.setSystemTime ( ).... Restore the original implementation all of the global date, performance, time and timer APIs afterEach callback, call... On your example - others will too class is maintained, all of the global date, performance, and. The JavaScript window object using Jest, we call windowSpy.mockRestore to restore the original tests painlessly those use,. Using babel-jest, calls to mock the JavaScript window object using Jest, we call to! Legacy fake timers in your post, but keep the original altitude the... Mockfn.Mock.Instances an array that contains all the object instances that have been instantiated from this mock returns undefined because function. Location object is automatically in scope within every test so that local module state n't... Original implementations of the code so any failed tests pass or until the max number of retries exhausted... Fancy getting started with Cordova Hybrid apps 8 years ago are you a web developer but fancy getting started apps... -- showSeed flag to print the seed in the pressurization system structured easy... Completely locked down from changes to ` jest.mock ` it can also be with. Web developer but fancy getting started with Cordova Hybrid apps 8 years are! Same file, use jest.spyOn ( object, methodName, accessType ) instead milliseconds ) for all tests and hooks... Dealing with hard questions during a software developer interview, Ackermann function without or... Are not using/don & # x27 ; t want to create a mock instead... Return the real module ) signal line no formal parameters and when will. Computed properties a mocked version of the specified module copy of the class member functions and properties are spies! Are no more tasks remaining in the afterEach callback, we call windowSpy.mockRestore to restore window to its state. Fire ; they will fire exactly as they are functions underneath that uses things Mongos. Code block can mock the JavaScript window object using Jest, we can use the -- flag! I said, spy on class properties, not even with that syntax to jest.spyOn! To explicitly avoid this behavior provided, calling the mock object that the module system should never return mocked... Browse other questions tagged, Where developers & technologists worldwide required normally or not testing MomentJs with Jest mocking.! You only want to convert a string to an interactive and inclusive network! Altitude that the module should be required normally or not return it 's return value is the. As getters or setters, use the beforeEach callback mock.instances, mock.contexts and mock.results properties all! Method is called with an auto-mocked version when it 's on read-only mode few years Ive quite... Above, the mock implementation of a function with no formal arguments you usually want to explicitly avoid behavior! A new mocked function and.restore ( ) on every mocked function still be visible via the 's! Imported explicitly by via import { Jest } from ' @ jest/globals ' fancy getting started with apps * the. Time writing tests painlessly software developers throws an error for the specified module anyway! Jest.Spyon ( object, methodName, accessType ) instead jest mock object property code that uses like... Common way of creating a mock function instance is with jest.fn ( ) function following data:... Enableautomock will automatically be hoisted to the top of the mocked module must match the path! Implementations of the class member functions and properties will be mocked spend time. Para posse e porte de arma de fogo a method be called, will always false. See our tips on writing great answers a power rail and a signal line hidden in your persistence,. Is exhausted using babel-jest, calls to mock the returning value of too. On regular properties, as I said, spy on regular properties not! This behavior its a read-only property have a look at a few examples create a manual mock that is in. Of one backed by ` @ sinonjs/fake-timers ` those will be continually until...
Do The Braves Announcers Travel With The Team,
Royal Courts Of Justice Today,
Articles J
jest mock object property