cyberangles blog

Chai BDD: How to Assert a String is One of Array Elements with `expect`

In modern software development, testing is a cornerstone of ensuring reliability and correctness. When writing tests, especially in behavior-driven development (BDD), clear and expressive assertions are key to making tests readable and maintainable. Chai, a popular assertion library for JavaScript, provides a rich set of BDD-style assertions via its expect interface, making it easy to validate conditions like "a string is one of the elements in an array."

Whether you’re testing user input, API responses, or function outputs, checking if a string exists in a predefined list of allowed values is a common scenario. For example:

  • Validating that a user’s role is one of ["admin", "editor", "viewer"].
  • Ensuring an API returns a status code like "success" or "error".
  • Confirming a dropdown selection matches one of the allowed options.

In this blog, we’ll dive deep into how to use Chai’s expect interface to assert that a string is an element of an array. We’ll cover basic usage, edge cases, case sensitivity, and real-world examples to help you master this essential testing skill.

2025-12

Table of Contents#

  1. What is Chai BDD and expect?
  2. Setup: Installing Chai
  3. Core Assertion: to.be.oneOf
  4. Handling Case Sensitivity
  5. Edge Cases to Consider
  6. oneOf vs. include: When to Use Which?
  7. Real-World Example: Testing API Responses
  8. Conclusion
  9. References

What is Chai BDD and expect?#

Chai is a BDD/TDD assertion library for Node.js and the browser, designed to work with testing frameworks like Mocha, Jest, or Jasmine. It offers three assertion styles: should, expect, and assert.

The expect interface is particularly popular for BDD because it uses a chainable, natural-language syntax (e.g., expect(value).to.equal(42)), making tests read like plain English. This style avoids extending native JavaScript objects (unlike should), which can cause issues in some environments.

Setup: Installing Chai#

Before using Chai, ensure you have a testing framework (e.g., Mocha) installed. If not, set up a basic project:

  1. Initialize a Node.js project (if needed):

    npm init -y  
  2. Install Chai and Mocha as dev dependencies:

    npm install chai mocha --save-dev  
  3. In your test file (e.g., string-in-array.test.js), import expect from Chai:

    const { expect } = require('chai');  

Now you’re ready to write assertions!

Core Assertion: to.be.oneOf#

To check if a string (or any value) is an element of an array, Chai provides the to.be.oneOf assertion. This method verifies that the target value is strictly equal (===) to at least one element in the provided array.

Basic Example#

Let’s start with a simple test: Assert that the string "apple" is one of the elements in ["banana", "apple", "orange"].

Test Code:

describe('String in Array Check', () => {  
  it('should pass if the string is in the array', () => {  
    const fruit = 'apple';  
    const fruits = ['banana', 'apple', 'orange'];  
 
    // Assert: "apple" is one of the elements in fruits  
    expect(fruit).to.be.oneOf(fruits);  
  });  
 
  it('should fail if the string is NOT in the array', () => {  
    const fruit = 'grape';  
    const fruits = ['banana', 'apple', 'orange'];  
 
    // This will fail (grape is not in fruits)  
    expect(fruit).to.be.oneOf(fruits);  
  });  
});  

Output (when run with Mocha):

  • The first test passes: ✓ should pass if the string is in the array.
  • The second test fails with an error:
    AssertionError: expected 'grape' to be one of [ 'banana', 'apple', 'orange' ]  
    

How It Works#

expect(value).to.be.oneOf(array) works by iterating over array and checking if value is strictly equal (===) to any element. For strings, this means the check is case-sensitive and type-sensitive (e.g., "123"123).

Handling Case Sensitivity#

Since to.be.oneOf uses strict equality (===), case differences will cause the assertion to fail. For example, "Apple" (capital "A") will not match "apple" (lowercase "a"):

Example:

it('fails for case differences', () => {  
  const fruit = 'Apple'; // Capital "A"  
  const fruits = ['apple', 'banana', 'orange']; // Lowercase "a"  
 
  expect(fruit).to.be.oneOf(fruits); // Fails!  
});  

Fix for Case-Insensitive Checks:
To ignore case, normalize both the target string and array elements (e.g., convert to lowercase):

it('passes with case-insensitive check', () => {  
  const fruit = 'Apple';  
  const fruits = ['apple', 'banana', 'orange'];  
 
  // Normalize to lowercase  
  const normalizedFruit = fruit.toLowerCase();  
  const normalizedFruits = fruits.map(f => f.toLowerCase());  
 
  expect(normalizedFruit).to.be.oneOf(normalizedFruits); // Passes!  
});  

Edge Cases to Consider#

Empty Arrays#

If the array is empty, to.be.oneOf will always fail (since there are no elements to match):

it('fails when array is empty', () => {  
  const fruit = 'apple';  
  const emptyArray = [];  
 
  expect(fruit).to.be.oneOf(emptyArray); // Fails: "expected 'apple' to be one of []"  
});  

Non-String Elements in the Array#

If the array contains non-string elements (e.g., numbers, objects), to.be.oneOf will only pass if the target string strictly matches a string element. Non-string elements will not match:

it('ignores non-string elements', () => {  
  const value = '42'; // String  
  const mixedArray = [42, 'banana', { key: 'value' }]; // Number, string, object  
 
  expect(value).to.be.oneOf(mixedArray); // Fails: "42" (string) ≠ 42 (number)  
});  

Null/Undefined Strings#

If the target string is null or undefined, to.be.oneOf will check if null/undefined exists in the array:

it('handles null/undefined', () => {  
  expect(null).to.be.oneOf([null, 'apple']); // Passes  
  expect(undefined).to.be.oneOf(['banana', undefined]); // Passes  
  expect(null).to.be.oneOf(['apple', 'banana']); // Fails  
});  

oneOf vs. include: When to Use Which?#

Chai also has an include assertion for arrays, which checks if the array contains a value. How does this differ from oneOf?

  • expect(value).to.be.oneOf(array): The subject is the value; asserts the value is an element of the array.
  • expect(array).to.include(value): The subject is the array; asserts the array includes the value.

Both use strict equality (===), but the syntax depends on what you’re testing. Use oneOf when the value is the focus (e.g., "this string should be one of these options"), and include when the array is the focus (e.g., "this array should include the string").

Real-World Example: Testing API Responses#

Let’s apply this to a common scenario: testing that an API returns a valid status for a user. Suppose an endpoint /api/users/1 returns a JSON object with a status field, which must be "active", "inactive", or "pending".

Test Code:

const { expect } = require('chai');  
const request = require('supertest'); // For API testing  
const app = require('../app'); // Your Express app  
 
describe('GET /api/users/1', () => {  
  it('responds with a valid status', async () => {  
    const response = await request(app).get('/api/users/1');  
 
    // Assert status is 200 OK  
    expect(response.status).to.equal(200);  
 
    // Assert user status is one of allowed values  
    const allowedStatuses = ['active', 'inactive', 'pending'];  
    expect(response.body.status).to.be.oneOf(allowedStatuses);  
  });  
});  

This test ensures the API behaves as expected, catching invalid statuses (e.g., "banned") early.

Conclusion#

Chai’s to.be.oneOf assertion is a powerful tool for checking if a string (or any value) is an element of an array. Its strict equality check ensures precision, and with minor adjustments (like normalization for case insensitivity), it handles most real-world scenarios.

Key takeaways:

  • Use expect(string).to.be.oneOf(array) to assert a string is in an array.
  • Remember strict equality (===) for case and type sensitivity.
  • Normalize strings/arrays for case-insensitive checks.
  • Handle edge cases like empty arrays or non-string elements explicitly.

By mastering this assertion, you’ll write more robust, readable tests for validating allowed values in your applications.

References#