1

I'm trying to test a function in a contract that sends ether from itself to another contract address. However in my Truffle tests I keep getting Uncaught Error: Error: could not unlock signer account. I have tried web3.personal.unlockAccount, however that doesn't appear to be supported in TestRPC?

Running TestRPC with -u flags doesn't help either because the contract address isn't in the list of accounts.

I thought it might be possible by using --fork but since Truffle does a fresh deploy on every test I can't get the deploy address to run -u <address> with --fork :(.

How can I either unlock this account so that I can test the functionality with Truffle, or workaround this to test that function?

4

I might be mistaken, but it sounds like a little confusion in the way you're setting up the test.

You can't use truffle to make the deployed contract do anything directly. In fact, in ethereum, everything starts when someone signs a transaction and sends it. So, you can only send a transaction to the contract you want to test. To do that, one of the accounts testrpc gives you will have to sign the transaction.

So, your contract at 0x123 might look something like:

contract TestSend {

  function sendToOther(address receiver) payable returns(bool success) {
    if(!receiver.send(msg.value) throw; // send whatever was received

...

Maybe truffle gives you:

0x456
0x789
...

You could tell truffle to send from a sender to a receiver (first argument) and you would send that transaction to 0x123 which would be TestSend.deployed():

testSend.sendToOther("0x789", {from: 0x456, value: 1})

where testSend is TestSend.deployed().

In the example, the signer would be 0x456. The point being that it is one the accounts testrpc gives you. It has to be. There is no other way.

In case it helps ... It's a matter of style, but I like to start my tests by declaring all the players. Something like below gets things off to a good start so you can say things like testSend.sendToOther(catcher,{from: sender, value: sendAmt});


var Contract = artifacts.require("./Contract.sol");

contract('Contract', function(accounts) {

  var contract;
  var sendAmt = 10;
  var owner   = accounts[0];
  var sender  = accounts[1];
  var catcher = accounts[2];

  beforeEach(function() {
    return Contract.new({from: owner})
    .then(function(instance) {
       contract = instance;
    });
  });

  it("should ...

Hope it helps.

  • Hi Rob, this was great. I definitely had a misunderstanding of how I was writing the tests. It's all working now :). Thanks a lot – Elliott McNary Jun 8 '17 at 15:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.