Contrato inteligente simulado para pruebas unitarias

Soy nuevo en Ethereum y solidity, estoy desarrollando una aplicación descentralizada simple usando Truffle donde tengo un contrato abstracto Storagey otro contrato Readerque usa almacenamiento.

contract Storage {
    function getWeight() public view returns(uint8);
    function setWeight(uint8 weight) public view returns(bool); 
}

contract Reader {
    Storage private storage;
    constructor(address storageAddress) {
        storage = Storage(storageAddress);
    }
}

Estoy tratando de escribir una prueba unitaria para el contrato Reader, ¿hay alguna forma de burlarse del comportamiento del contrato abstracto? Si no, ¿cuáles son las mejores prácticas para esa situación?

Respuestas (2)

Creé una pequeña implementación del contrato de almacenamiento. Tenga en cuenta que cambié el nombre de su abstracción a StorageInterface.

También agregué algunas funciones a Reader, ya que no hay mucho que probar a menos que haga algo. Entonces, ahora tiene un setter/getter en Reader que reenvía a un contrato de almacenamiento que es una implementación de la interfaz.

Al mirarlo, decidí que no me sentía cómodo con el uso de "Almacenamiento" porque esta es una palabra reservada en minúsculas. También prescindí de lo uint8que parece una optimización prematura.

Otra cosita más. La interfaz declaró el setter como view, pero no puede serlo ya que escribe en el estado del contrato.

pragma solidity 0.4.24;

contract StoreInterface {
    function getWeight() public view returns(uint);
    function setWeight(uint weight) public returns(bool); 
}

/**
 * Just a very simple set of stubs ...
 * Deploy a "Store" and then pass its address into Reader's constructor.
 */

contract Store is StoreInterface {

    uint weight;

    event LogSetWeight(address sender, uint weight);

    function getWeight() public view returns(uint) {
        return weight;
    }

    function setWeight(uint _weight) public returns(bool) {
        weight = _weight;
        emit LogSetWeight(msg.sender, _weight);
        return true;
    } 
}

contract Reader {

    StoreInterface store;

    constructor(address storeAddress) public {
        store = StoreInterface(storeAddress);
    }

    function getWeight() public view returns(uint) {
        return store.getWeight();
    }

    function setWeight(uint weight) public returns(bool) {
        return store.setWeight(weight);
    }
}

Espero eso ayude.

El otro enfoque sería usar una biblioteca simulada, como Doppelganger