> For AI agents: the complete documentation index is available at https://rslint.rs/llms.txt, the full documentation bundle is available at https://rslint.rs/llms-full.txt.

# unbound-method

[Added in v0.9.3](https://github.com/web-infra-dev/rslint/releases/tag/v0.9.3)
## Configuration

| Preset                     | Configured Value |
| -------------------------- | ---------------- |
| ✅ rstestPlugin.configs.all | `"warn"`         |


```ts title=rslint.config.ts
import { defineConfig, rstestPlugin } from '@rslint/core';

export default defineConfig([
  rstestPlugin.configs.recommended,
  {
    rules: {
      'rstest/unbound-method': 'error',
    },
  },
]);
```

## Rule Details

This rule reports class and object methods that are referenced without their receiver. Calling such a reference later can give the method an unintended `this` value. The rule uses TypeScript type information to distinguish methods from bound function properties, functions declared with `this: void`, and built-in functions that can safely be referenced directly.

Rstest-aware exemptions apply when a method reference is the received value of `expect(...)` or `expect.soft(...)` and the built-in matcher inspects the value without invoking it. This includes mock, equality, and Chai-style value assertions. Snapshot assertions are not exempt because custom snapshot serializers can invoke the received function, including serializers registered in setup files. `toThrow`, `toThrowError`, Chai `throw` and `throws`, and the `rejects` modifier also continue to report unbound methods. The `resolves` modifier does not invoke a function subject and follows the matcher behavior.

If the file replaces a built-in matcher with `expect.extend()`, that matcher is not exempt. Equality-based matchers are likewise not exempt after the file calls `expect.addEqualityTesters()`, or when a value compared directly with the received method is a custom asymmetric matcher with a callable `asymmetricMatch` member, because that user code can execute the received function. The invoking built-in factories `expect.toSatisfy()` and `expect.schemaMatching()` remain diagnostic, and `toBeOneOf()` also remains diagnostic when a direct array or `Set` sample may invoke the received method. Built-in asymmetric matchers with known non-invoking behavior remain exempt. These checks also follow stable local aliases of matcher values and collections. Extensions and equality testers loaded only through other files are not detected.

The rule also allows a method reference passed directly to `mocked()` on an Rstest utilities object. It recognizes the `rs` and `rstest` globals, imports and renamed imports from `@rstest/core` or `rstack/test`, module namespaces, CommonJS bindings, and `import.meta.rstest`. Static string and template accessors, such as `core['rs'].mocked(...)`, are also recognized. Unrelated or locally shadowed objects with the same names are not treated as Rstest utilities. Writes to a recognized API root or its properties, including `import.meta.rstest`, disable its exemptions.

See the [Rstest expect API](https://rstest.rs/api/runtime-api/test-api/expect) and [mock utilities](https://rstest.rs/api/runtime-api/rstest/mock-functions) for the runtime behavior of these APIs.

## Incorrect

```ts
class Counter {
  count = 0;

  increment() {
    this.count += 1;
    return this.count;
  }
}

const counter = new Counter();

const increment = counter.increment;
expect(counter.increment).toThrow();
```

## Correct

```ts
class Counter {
  count = 0;

  increment() {
    this.count += 1;
    return this.count;
  }
}

const counter = new Counter();
rs.spyOn(counter, 'increment');

const increment = counter.increment.bind(counter);
expect(counter.increment).toHaveBeenCalled();
rs.mocked(counter.increment).mockReturnValue(2);
```

## Options

```json
{
  "rstest/unbound-method": [
    "error",
    {
      "ignoreStatic": true
    }
  ]
}
```

| Option         | Type      | Default | Description                     |
| -------------- | --------- | ------- | ------------------------------- |
| `ignoreStatic` | `boolean` | `false` | Skip checks for static methods. |
