Best Practices for Enhancing Testability of Wrapper Methods

Recently, I have implemented a practice in my tests where I encapsulate error messages and string manipulations into methods or variables to enhance the resilience of my tests in case the content of error messages changes in the future.

For instance, I would modify code like this:

try{
    someMethod();
}catch(e){
    throw new Error('error message.');
}

to something like this:

let errorMessage = 'error message';
...
try{
    someMethod();
}catch(e){
    throw new Error(errorMessage);
}

I apply similar modifications if the error message involves a variable or other dynamic elements.

My inquiry pertains to the best approach to achieve this in Typescript. In Java, I usually designate them as package-protected, but it appears that Jasmine does not have access to such methods when they are protected. I also experimented with making them static.

Is there a recommended strategy for handling this scenario?

Answer №1

It's always beneficial to adopt best practices from various programming languages on certain occasions.

By creating custom exceptions, you can easily verify their type instead of relying on error strings, promoting consistency in error handling.

While this example may seem complex, it demonstrates the concept well (adapted from pages 163-168 of Pro Typescript).

  1. We begin by defining a base CustomException class that implements the Error interface and serves as the foundation for all custom error types in our application.
  2. An InvalidDateException is then created to represent a specific type of error, centralizing the error message within the application.
  3. With this setup, we can easily identify different error types using an instanceof check, as shown in the catch statement example.
  4. All custom exceptions are designed to align with the Error interface requirements, which include implementing name and toString() methods.

Code:

class CustomException implements Error {
    protected name = 'CustomException';

    constructor(public message: string) {
    }

    toString() {
        return this.name + ': ' + this.message;
    }
}

class InvalidDateException extends CustomException {
    constructor(public date: Date) {
        super('The date supplied was not valid: ' + date.toISOString());
        this.name = 'InvalidDateException';
    }
}

try {
    throw new InvalidDateException(new Date());
} catch (ex) {
    if (ex instanceof InvalidDateException) {
        alert(ex.toString());
    }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Creating effective puppeteer tests with reasonable expectations

Imagine I have a list of objects and a create button. Typically, the objects are created quickly without any loading indicator. Here is an example of my creation test: const items = await page.$$('.item'); const itemsCount = items.length; await ...

Tips for extracting the value of T from a Promise<T>

I have a scenario where an async function is declared with a return type as follows: async function getNumber() { const {number} = await API_getNumber(); return number; } export type Return = ReturnType<typeof getNumber> In this case, Return ...

Basic exam but located in a place that is not valid

Here is a test I am working on: // import {by, element, browser} from "protractor"; describe('intro', () => { beforeEach(() => { browser.get(''); }); it('should have multiple pages', () => { let buttonOn ...

View the generated tsconfig file after including { "extends": ... }

Currently, I am working on my Angular project using WebStorm which involves multiple tsconfig files such as tsconfig.json, tsconfig.lib.json, tsconfig.lib.prod.json, and tsconfig.spec.json. While most of the configuration settings are only in the main tsc ...

When importing a React Component with styling into the pages folder, it fails to function properly

I created a component in my components directory with custom styling: // import Link from "next/link"; import {Link} from "react-scroll" export default function Navbar() { return ( <div className="fixed w-full h-[79px] fle ...

How to turn off automatic password suggestions in Chrome and Firefox

Currently, I have integrated a 'change password' feature which includes fields for 'old password', 'new password', and 'retype password'. However, the autocomplete feature is suggesting passwords from other user acco ...

Encountering a 'scheduler flush execution error' and an Uncaught TypeError due to VueJS and Axios integration

After carefully examining my code, I have pinpointed the cause of this error to the following line: treeNodes.value = documentStore.convertToTree((await axios.get('/File')).data); Initially, I receive a warning: Vue warn]: Unhandled error during ...

Determining object keys based on the values of other keys to customize functions

In search of a way to create a function with statically typed input object keys based on certain key values, I have created a TypeScript playground containing a failing test. Click the link below to access the playground: Playground Link export type Input ...

Tips for confining the draggable div within its container

I've been working with React and TypeScript, and I recently added the W3School drag div example to my React app. However, I'm facing an issue where the draggable div is moving outside of the container. Can someone please guide me on how to confin ...

What are some techniques to ensure null checking is enforced for objects that are nested within multiple layers

Currently, I am leveraging redux sagas to fetch data asynchronously from various endpoints using a unified interface: export interface ResponseInfo { data?: any; status: number; headers?: any; subCode?: string; } To ensure that null check ...

Using React with Typescript: Can the parent component access data fetched from a nested child component?

Can I access data retrieved from a child component (using a graphql query) in a parent component? For example, how can I use the data fetched by React-component-4 in React-component-1? Is there a way to do this or do I have to duplicate the data fetching ...

Tips for accessing the following element within an array using a for loop with the syntax for (let obj of objects)

Is there a way to access the next element in an array while iterating through it? for (let item of list) { // accessing the item at index + 1 } Although I am aware that I could use a traditional for loop, I would rather stick with this syntax. for (i ...

Why is the variable suddenly a number when I clearly defined it as a string?

Let's start with the following code snippet: let vAny: any = 10 let s1: string = vAny; console.log(typeof s1) In this scenario, I have explicitly defined that s1 should be a string. However, when inspecting the type of s1, it shows up as a number in ...

When in debug mode, the Unit Test Sessions Window automatically closes

After choosing an NUnit test in the Unit Test Sessions window and clicking debug, the window seems to vanish. Although my breakpoints are being hit, the Unit Test Sessions window does not reappear until the test produces a result or I end the debugging s ...

Tips for managing the output of an asynchronous function in TypeScript

The casesService function deals with handling an HTTP request and response to return a single object. However, due to its asynchronous nature, it currently returns an empty object (this.caseBook). My goal is for it to only return the object once it has b ...

Best practices for effectively sharing TypeScript code across multiple Aurelia CLI projects

Currently, I am working on developing a local Node package using TypeScript that can be imported into multiple Aurelia CLI projects within the same solution. To showcase my progress, I have set up a sample solution at: https://github.com/sam-piper/aureli ...

A Step-by-Step Guide on Updating Your Angular 7 Project to Angular Version

I am facing a challenge with my Angular material project, which is currently outdated and needs to be updated to version 13. Running npm outdated revealed the following results: https://i.stack.imgur.com/ayjDu.png The Angular update guide suggests upgra ...

Differentiating TypeScript classes is important in situations where they would normally be treated as equivalent

Looking to add a lightweight layer on top of Float32Array to create vec2 and vec3's. Check out the example below: class vec3 extends Float32Array { // w : number; constructor() { super(3); // this.w = 1; } static add3(x: ...

What could be causing this object to be null or undefined when it's within an else if statement?

Below is the code snippet used in a component: Component.svelte: <script lang="ts"> type T = $$Generic; export let loading = false; export let error = false; export let value: T | null | undefined = undefined; </script ...

The service fails to recognize the ActivatedRoute

Using ActivatedRoute in Services The Challenge Attempting to utilize ActivatedRoute within a service, I encountered an issue where it was not tracking the current route accurately. It seemed unable to detect any route at all. After spending considerable ...