es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo probar correctamente un revert para el modificador ‘onlyOwner’?

En mi contrato Solidity que hereda de Ownable y AccessControl de OpenZeppelin, tengo una función que el propietario del contrato puede llamar para otorgar a una cuenta el rol de ADMIN. Se ve así:

function addAdmin(address account) public virtual onlyOwner {
   _grantRole(ADMIN, account);
}

En mi archivo de prueba estoy utilizando test-environment y test-helper de OpenZeppelin con Mocha y Chai. Estoy intentando probar el fallo de llamar a addAdmin() desde una cuenta que no es del propietario. Mi prueba se ve así:

it('denies access to non-Owners to add a new ADMIN', async function() {
   await expectRevert(
      await pool.addAdmin(notlisted1, { from: notlisted2 }),
      "Ownable: caller is not the owner"
   );
});

Parece que addAdmin() revierte correctamente, pero la prueba falla. El mensaje que veo en la línea de comandos cuando falla esta prueba es:

Error: Returned error: VM Exception while processing transaction: revert Ownable: caller is not the owner -- Reason given: Ownable: caller is not the owner.

¿Alguna idea de qué está sucediendo aquí? ¿Por qué no pasa la aserción de expectRevert()?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Parece que la afirmación en la función expectRevert() está verificando un mensaje de error diferente al que la función realmente lanza. El mensaje de error devuelto por la función es Ownable: caller is not the owner, que coincide con el mensaje de error que se pasó a la aserción expectRevert(). Sin embargo, el mensaje de error que se muestra en la consola es ligeramente diferente, lo que hace que la prueba falle.

    Para solucionar este problema, debes modificar tu prueba para usar el método assert para verificar el mensaje de error. Aquí tienes un ejemplo de cómo puedes hacer esto:

    it('Niega el acceso a los no propietarios para agregar un nuevo ADMIN', async function() {
       await assert.rejects(
          pool.addAdmin(notlisted1, { from: notlisted2 }),
          (error) => {
             assert(error.message.includes('Ownable: caller is not the owner'), "Mensaje de error esperado");
             return true;
          }
       );
    });
    

    En este ejemplo, se utiliza el método assert.rejects() para comprobar que la llamada a la función lanza un error. El segundo argumento de este método es una función de devolución de llamada que toma el error lanzado como argumento. En esta función de devolución de llamada, utilizamos el método assert() para verificar que el mensaje de error contiene la cadena esperada. Esto debería garantizar que la prueba pase cuando la función addAdmin() lance el error con el mensaje esperado.

Comments are closed.