DenMette's avatar

Writing tests for a Attribute Mutator.

I have written a custom Attribute, and I also like to test my getter. The only problem is I need to figure out how. Writing the tests for the setter part was simple to do. My preferred stack for writing tests is PestPHP.

The method to test

protected function role(): Attribute
{
    return Attribute::make(
        get: function (mixed $role) {
            if (is_null($role)) {
                throw new InvalidArgumentException('Role is a required field.');
            }

            if (!is_numeric($role)) {
                throw new InvalidArgumentException("Invalid value for role.");
            }

            return Role::from(intval($role));
        },
        set: function (mixed $role) {
            if (is_null($role)) {
                throw new InvalidArgumentException('Role is a required field.');
            }

            if ($role instanceof Role) {
                return $role->value;
            }

            if (!is_numeric($role)) {
                throw new InvalidArgumentException("Invalid value for role.");
            }

            return intval($role);
        },
    );
}

The setter that I have written so far

describe('Setting the role value', function() {
    it('converts string numeric value to integer', function () {
        // Call the method with a string containing a numeric value
        $result = User::factory()->make([
            'role' => '2',
        ]);

        // Assert that the result is the integer representation of the string
        expect($result->role)->toBe(Role::SUPERVISOR);
    });

    it('converts numeric value to integer', function () {
        // Call the method with a numeric value
        $result = User::factory()->make([
            'role' => 4,
        ]);

        // Assert that the result is the integer representation of the string
        expect($result->role)->toBe(Role::UNKNOWN);
    });

    it('converts Role value to integer', function () {
        // Call the method with a Role value
        $result = User::factory()->make([
            'role' => Role::OWNER,
        ]);

        // Assert that the result is the integer representation of the string
        expect($result->role)->toBe(Role::OWNER);
    });

    it('throws exception for invalid role value', function () {
        // Call the method with a string
        User::factory()->make([
            'role' => 'owner',
        ]);
    })->throws(InvalidArgumentException::class, "Invalid value 'owner' for role.");

    it('throws exception for a null value', function () {
        // Call the method with a string
        User::factory()->make([
            'role' => null,
        ]);
    })->throws(InvalidArgumentException::class, 'Role is a required field.');
});
0 likes
0 replies

Please or to participate in this conversation.