Watch 10 video solutions for To Be Or Not To Be, a easy level problem. This walkthrough by Endeavour Monk has 9,164 views views. Want to try solving it yourself? Practice on FleetCode or read the detailed text solution.
Write a function expect that helps developers test their code. It should take in any value val and return an object with the following two functions.
toBe(val) accepts another value and returns true if the two values === each other. If they are not equal, it should throw an error "Not Equal".notToBe(val) accepts another value and returns true if the two values !== each other. If they are equal, it should throw an error "Equal".
Example 1:
Input: func = () => expect(5).toBe(5)
Output: {"value": true}
Explanation: 5 === 5 so this expression returns true.
Example 2:
Input: func = () => expect(5).toBe(null)
Output: {"error": "Not Equal"}
Explanation: 5 !== null so this expression throw the error "Not Equal".
Example 3:
Input: func = () => expect(5).notToBe(null)
Output: {"value": true}
Explanation: 5 !== null so this expression returns true.
Problem Overview: You implement a tiny assertion utility similar to what testing frameworks provide. The function expect(val) returns an object with two methods: toBe(val2) and notToBe(val2). If the condition fails, the method throws an error. Otherwise it returns true. The challenge is mainly about structuring the returned behavior using language features such as closures or object-oriented programming.
Approach 1: Closure-Based Approach (O(1) time, O(1) space)
The closure approach captures the original value inside the scope of expect. The function returns an object containing toBe and notToBe methods, and both methods reference the captured value. When toBe(val2) runs, it directly compares the stored value with val2. If they are strictly equal, return true; otherwise throw an error such as "Not Equal". The notToBe method performs the opposite check and throws an error like "Equal" when the values match. This works because closures preserve access to variables defined in the outer function even after that function finishes execution.
The key insight is that you do not need persistent state outside the function. The captured variable inside the closure behaves like private data. This makes the implementation concise and idiomatic in languages such as JavaScript or Python where functions can return objects containing nested functions.
Approach 2: Class-Based Approach (O(1) time, O(1) space)
The class-based design wraps the value inside an instance field. Instead of relying on lexical scope, the stored value becomes a property of the class object. The constructor receives the value, and the methods toBe and notToBe operate on that stored field.
During execution, expect(val) simply returns a new instance of the class. Each method performs a direct equality comparison with the stored value and throws the appropriate error when the condition fails. This approach mirrors how many testing libraries internally implement assertions. It fits naturally in strongly object-oriented languages such as C++, Java, and C# where encapsulation through classes is the standard pattern.
The advantage is structural clarity. State and behavior are grouped inside a single class, which makes the implementation straightforward when closures are less idiomatic or unavailable.
Recommended for interviews: The closure-based implementation is typically the expected answer when the problem is asked in JavaScript because it demonstrates understanding of closures and lexical scope. The class-based approach is equally correct and often preferred in languages centered around object-oriented design. Interviewers mainly look for correct comparison logic, proper error handling, and a clean API design.
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Closure-Based Implementation | O(1) | O(1) | Best for JavaScript/Python when demonstrating closure and lexical scope concepts |
| Class-Based Implementation | O(1) | O(1) | Preferred in C++, Java, and C# where object-oriented patterns are standard |