@@ -1481,6 +1481,185 @@ describe('moduleMocker', () => {
14811481 expect ( spy ) . toHaveBeenCalled ( ) ;
14821482 } ) ;
14831483
1484+ it ( 'supports clearing a spy' , ( ) => {
1485+ let methodOneCalls = 0 ;
1486+ const obj = {
1487+ methodOne ( ) {
1488+ methodOneCalls ++ ;
1489+ } ,
1490+ } ;
1491+
1492+ const spy1 = moduleMocker . spyOn ( obj , 'methodOne' ) ;
1493+
1494+ obj . methodOne ( ) ;
1495+
1496+ // The spy and the original function are called.
1497+ expect ( methodOneCalls ) . toBe ( 1 ) ;
1498+ expect ( spy1 . mock . calls ) . toHaveLength ( 1 ) ;
1499+
1500+ expect ( moduleMocker . isMockFunction ( obj . methodOne ) ) . toBe ( true ) ;
1501+
1502+ spy1 . mockClear ( ) ;
1503+
1504+ // After clearing the spy, the method is still mock function.
1505+ expect ( moduleMocker . isMockFunction ( obj . methodOne ) ) . toBe ( true ) ;
1506+
1507+ // After clearing the spy, call count is reset.
1508+ expect ( spy1 . mock . calls ) . toHaveLength ( 0 ) ;
1509+ } ) ;
1510+
1511+ it ( 'supports clearing all spies' , ( ) => {
1512+ let methodOneCalls = 0 ;
1513+ let methodTwoCalls = 0 ;
1514+ const obj = {
1515+ methodOne ( ) {
1516+ methodOneCalls ++ ;
1517+ } ,
1518+ methodTwo ( ) {
1519+ methodTwoCalls ++ ;
1520+ } ,
1521+ } ;
1522+
1523+ const spy1 = moduleMocker . spyOn ( obj , 'methodOne' ) ;
1524+ const spy2 = moduleMocker . spyOn ( obj , 'methodTwo' ) ;
1525+
1526+ obj . methodOne ( ) ;
1527+ obj . methodTwo ( ) ;
1528+
1529+ // Both spies and both original functions are called.
1530+ expect ( methodOneCalls ) . toBe ( 1 ) ;
1531+ expect ( methodTwoCalls ) . toBe ( 1 ) ;
1532+ expect ( spy1 . mock . calls ) . toHaveLength ( 1 ) ;
1533+ expect ( spy2 . mock . calls ) . toHaveLength ( 1 ) ;
1534+
1535+ expect ( moduleMocker . isMockFunction ( obj . methodOne ) ) . toBe ( true ) ;
1536+ expect ( moduleMocker . isMockFunction ( obj . methodTwo ) ) . toBe ( true ) ;
1537+
1538+ moduleMocker . clearAllMocks ( ) ;
1539+
1540+ // After clearing all mocks, the methods are still mock functions.
1541+ expect ( moduleMocker . isMockFunction ( obj . methodOne ) ) . toBe ( true ) ;
1542+ expect ( moduleMocker . isMockFunction ( obj . methodTwo ) ) . toBe ( true ) ;
1543+
1544+ // After clearing all mocks, call counts are reset.
1545+ expect ( spy1 . mock . calls ) . toHaveLength ( 0 ) ;
1546+ expect ( spy2 . mock . calls ) . toHaveLength ( 0 ) ;
1547+ } ) ;
1548+
1549+ it ( 'supports resetting a spy' , ( ) => {
1550+ const methodOneReturn = 10 ;
1551+ let methodOneRealCalls = 0 ;
1552+ const obj = {
1553+ methodOne ( ) {
1554+ methodOneRealCalls ++ ;
1555+ return methodOneReturn ;
1556+ } ,
1557+ } ;
1558+
1559+ const spy1 = moduleMocker . spyOn ( obj , 'methodOne' ) . mockReturnValue ( 100 ) ;
1560+
1561+ // Return value is mocked.
1562+ expect ( obj . methodOne ( ) ) . toBe ( 100 ) ;
1563+ // Real impl has not been used.
1564+ expect ( methodOneRealCalls ) . toBe ( 0 ) ;
1565+
1566+ expect ( moduleMocker . isMockFunction ( obj . methodOne ) ) . toBe ( true ) ;
1567+
1568+ spy1 . mockReset ( ) ;
1569+
1570+ // After resetting the spy, the method is still mock functions.
1571+ expect ( moduleMocker . isMockFunction ( obj . methodOne ) ) . toBe ( true ) ;
1572+
1573+ // After resetting the spy, the method returns undefined.
1574+ expect ( obj . methodOne ( ) ) . toBeUndefined ( ) ;
1575+
1576+ // Real implementation has still not been called.
1577+ expect ( methodOneRealCalls ) . toBe ( 0 ) ;
1578+ } ) ;
1579+
1580+ it ( 'supports resetting all spies' , ( ) => {
1581+ const methodOneReturn = 10 ;
1582+ const methodTwoReturn = { } ;
1583+ let methodOneRealCalls = 0 ;
1584+ let methodTwoRealCalls = 0 ;
1585+ const obj = {
1586+ methodOne ( ) {
1587+ methodOneRealCalls ++ ;
1588+ return methodOneReturn ;
1589+ } ,
1590+ methodTwo ( ) {
1591+ methodTwoRealCalls ++ ;
1592+ return methodTwoReturn ;
1593+ } ,
1594+ } ;
1595+
1596+ // methodOne is spied on and mocked.
1597+ moduleMocker . spyOn ( obj , 'methodOne' ) . mockReturnValue ( 100 ) ;
1598+ // methodTwo is spied on but not mocked.
1599+ moduleMocker . spyOn ( obj , 'methodTwo' ) ;
1600+
1601+ // Return values are mocked.
1602+ expect ( obj . methodOne ( ) ) . toBe ( 100 ) ;
1603+ expect ( obj . methodTwo ( ) ) . toBe ( methodTwoReturn ) ;
1604+
1605+ // The real implementation has not been called when mocked.
1606+ expect ( methodOneRealCalls ) . toBe ( 0 ) ;
1607+
1608+ // But has for the unmocked spy.
1609+ expect ( methodTwoRealCalls ) . toBe ( 1 ) ;
1610+
1611+ // Both are mock functions.
1612+ expect ( moduleMocker . isMockFunction ( obj . methodOne ) ) . toBe ( true ) ;
1613+ expect ( moduleMocker . isMockFunction ( obj . methodTwo ) ) . toBe ( true ) ;
1614+
1615+ moduleMocker . resetAllMocks ( ) ;
1616+
1617+ // After resetting all mocks, the methods are still mock functions.
1618+ expect ( moduleMocker . isMockFunction ( obj . methodOne ) ) . toBe ( true ) ;
1619+ expect ( moduleMocker . isMockFunction ( obj . methodTwo ) ) . toBe ( true ) ;
1620+
1621+ // After resetting all mocks, the methods are stubs returning undefined.
1622+ expect ( obj . methodOne ( ) ) . toBeUndefined ( ) ;
1623+
1624+ // NB: It may not be desirable for reset to stub a spy that was never mocked -
1625+ // consider changing in a future major.
1626+ expect ( obj . methodTwo ( ) ) . toBeUndefined ( ) ;
1627+
1628+ // Real functions have not been called any more times.
1629+ expect ( methodOneRealCalls ) . toBe ( 0 ) ;
1630+ expect ( methodTwoRealCalls ) . toBe ( 1 ) ;
1631+ } ) ;
1632+
1633+ it ( 'supports restoring a spy' , ( ) => {
1634+ let methodOneCalls = 0 ;
1635+ const obj = {
1636+ methodOne ( ) {
1637+ methodOneCalls ++ ;
1638+ } ,
1639+ } ;
1640+
1641+ const spy1 = moduleMocker . spyOn ( obj , 'methodOne' ) ;
1642+
1643+ obj . methodOne ( ) ;
1644+
1645+ // The spy and the original function got called.
1646+ expect ( methodOneCalls ) . toBe ( 1 ) ;
1647+ expect ( spy1 . mock . calls ) . toHaveLength ( 1 ) ;
1648+
1649+ expect ( moduleMocker . isMockFunction ( obj . methodOne ) ) . toBe ( true ) ;
1650+
1651+ spy1 . mockRestore ( ) ;
1652+
1653+ // After restoring the spy, the method is not mock function.
1654+ expect ( moduleMocker . isMockFunction ( obj . methodOne ) ) . toBe ( false ) ;
1655+
1656+ obj . methodOne ( ) ;
1657+
1658+ // After restoring the spy only the real method bumps its call count, not the spy.
1659+ expect ( methodOneCalls ) . toBe ( 2 ) ;
1660+ expect ( spy1 . mock . calls ) . toHaveLength ( 0 ) ;
1661+ } ) ;
1662+
14841663 it ( 'supports restoring all spies' , ( ) => {
14851664 let methodOneCalls = 0 ;
14861665 let methodTwoCalls = 0 ;
@@ -1649,6 +1828,85 @@ describe('moduleMocker', () => {
16491828 ) ;
16501829 } ) ;
16511830
1831+ it ( 'supports resetting a spy' , ( ) => {
1832+ const methodOneReturn = 0 ;
1833+ let methodOneRealCalls = 0 ;
1834+ const obj = {
1835+ get methodOne ( ) {
1836+ methodOneRealCalls ++ ;
1837+ return methodOneReturn ;
1838+ } ,
1839+ } ;
1840+
1841+ const spy1 = moduleMocker
1842+ . spyOn ( obj , 'methodOne' , 'get' )
1843+ . mockReturnValue ( 10 ) ;
1844+
1845+ // Return value is mocked.
1846+ expect ( obj . methodOne ) . toBe ( 10 ) ;
1847+
1848+ spy1 . mockReset ( ) ;
1849+
1850+ // After resetting the spy, the getter is a stub returning undefined
1851+ expect ( obj . methodOne ) . toBeUndefined ( ) ;
1852+ expect ( methodOneRealCalls ) . toBe ( 0 ) ;
1853+ } ) ;
1854+
1855+ it ( 'supports resetting all spies' , ( ) => {
1856+ const methodOneReturn = 10 ;
1857+ const methodTwoReturn = 20 ;
1858+ const obj = {
1859+ get methodOne ( ) {
1860+ return methodOneReturn ;
1861+ } ,
1862+ get methodTwo ( ) {
1863+ return methodTwoReturn ;
1864+ } ,
1865+ } ;
1866+
1867+ moduleMocker . spyOn ( obj , 'methodOne' , 'get' ) . mockReturnValue ( 100 ) ;
1868+ moduleMocker . spyOn ( obj , 'methodTwo' , 'get' ) . mockReturnValue ( 200 ) ;
1869+
1870+ // Return values are mocked.
1871+ expect ( methodOneReturn ) . toBe ( 10 ) ;
1872+ expect ( methodTwoReturn ) . toBe ( 20 ) ;
1873+ expect ( obj . methodOne ) . toBe ( 100 ) ;
1874+ expect ( obj . methodTwo ) . toBe ( 200 ) ;
1875+
1876+ moduleMocker . resetAllMocks ( ) ;
1877+
1878+ // After resetting all mocks, the methods are stubs
1879+ expect ( obj . methodOne ) . toBeUndefined ( ) ;
1880+ expect ( obj . methodTwo ) . toBeUndefined ( ) ;
1881+ } ) ;
1882+
1883+ it ( 'supports restoring a spy' , ( ) => {
1884+ let methodOneCalls = 0 ;
1885+ const obj = {
1886+ get methodOne ( ) {
1887+ return function ( ) {
1888+ methodOneCalls ++ ;
1889+ } ;
1890+ } ,
1891+ } ;
1892+
1893+ const spy1 = moduleMocker . spyOn ( obj , 'methodOne' , 'get' ) ;
1894+
1895+ obj . methodOne ( ) ;
1896+
1897+ // The spy and the original function are called.
1898+ expect ( methodOneCalls ) . toBe ( 1 ) ;
1899+ expect ( spy1 . mock . calls ) . toHaveLength ( 1 ) ;
1900+
1901+ spy1 . mockRestore ( ) ;
1902+
1903+ obj . methodOne ( ) ;
1904+
1905+ // After restoring the spy only the real method bumps its call count, not the spy.
1906+ expect ( methodOneCalls ) . toBe ( 2 ) ;
1907+ expect ( spy1 . mock . calls ) . toHaveLength ( 0 ) ;
1908+ } ) ;
1909+
16521910 it ( 'supports restoring all spies' , ( ) => {
16531911 let methodOneCalls = 0 ;
16541912 let methodTwoCalls = 0 ;
@@ -1754,6 +2012,87 @@ describe('moduleMocker', () => {
17542012 expect ( obj . property ) . toBe ( true ) ;
17552013 } ) ;
17562014
2015+ it ( 'supports resetting a spy on the prototype chain' , ( ) => {
2016+ let methodOneRealCalls = 0 ;
2017+ const prototype = {
2018+ get methodOne ( ) {
2019+ methodOneRealCalls ++ ;
2020+ return 1 ;
2021+ } ,
2022+ } ;
2023+ const obj = Object . create ( prototype , { } ) ;
2024+
2025+ const spy1 = moduleMocker
2026+ . spyOn ( obj , 'methodOne' , 'get' )
2027+ . mockReturnValue ( 10 ) ;
2028+
2029+ // Return value is mocked.
2030+ expect ( obj . methodOne ) . toBe ( 10 ) ;
2031+
2032+ spy1 . mockReset ( ) ;
2033+
2034+ // After resetting the spy, the method is a stub.
2035+ expect ( obj . methodOne ) . toBeUndefined ( ) ;
2036+
2037+ // The real implementation has not been used.
2038+ expect ( methodOneRealCalls ) . toBe ( 0 ) ;
2039+ } ) ;
2040+
2041+ it ( 'supports resetting all spies on the prototype chain' , ( ) => {
2042+ const methodOneReturn = 10 ;
2043+ const methodTwoReturn = 20 ;
2044+ const prototype = {
2045+ get methodOne ( ) {
2046+ return methodOneReturn ;
2047+ } ,
2048+ get methodTwo ( ) {
2049+ return methodTwoReturn ;
2050+ } ,
2051+ } ;
2052+ const obj = Object . create ( prototype , { } ) ;
2053+
2054+ moduleMocker . spyOn ( obj , 'methodOne' , 'get' ) . mockReturnValue ( 100 ) ;
2055+ moduleMocker . spyOn ( obj , 'methodTwo' , 'get' ) . mockReturnValue ( 200 ) ;
2056+
2057+ // Return values are mocked.
2058+ expect ( obj . methodOne ) . toBe ( 100 ) ;
2059+ expect ( obj . methodTwo ) . toBe ( 200 ) ;
2060+
2061+ moduleMocker . resetAllMocks ( ) ;
2062+
2063+ // After resetting all mocks, the methods are stubs
2064+ expect ( obj . methodOne ) . toBeUndefined ( ) ;
2065+ expect ( obj . methodTwo ) . toBeUndefined ( ) ;
2066+ } ) ;
2067+
2068+ it ( 'supports restoring a spy on the prototype chain' , ( ) => {
2069+ let methodOneCalls = 0 ;
2070+ const prototype = {
2071+ get methodOne ( ) {
2072+ return function ( ) {
2073+ methodOneCalls ++ ;
2074+ } ;
2075+ } ,
2076+ } ;
2077+ const obj = Object . create ( prototype , { } ) ;
2078+
2079+ const spy1 = moduleMocker . spyOn ( obj , 'methodOne' , 'get' ) ;
2080+
2081+ obj . methodOne ( ) ;
2082+
2083+ // The spy and the original function are called, because we have not mocked it.
2084+ expect ( methodOneCalls ) . toBe ( 1 ) ;
2085+ expect ( spy1 . mock . calls ) . toHaveLength ( 1 ) ;
2086+
2087+ spy1 . mockRestore ( ) ;
2088+
2089+ obj . methodOne ( ) ;
2090+
2091+ // After restoring the spy only the real method bumps its call count, not the spy.
2092+ expect ( methodOneCalls ) . toBe ( 2 ) ;
2093+ expect ( spy1 . mock . calls ) . toHaveLength ( 0 ) ;
2094+ } ) ;
2095+
17572096 it ( 'supports restoring all spies on the prototype chain' , ( ) => {
17582097 let methodOneCalls = 0 ;
17592098 let methodTwoCalls = 0 ;
0 commit comments