Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can JustMock return a value based on the parameter?

Using JustMock, can I arrange a mock to return something based on the input parameter?

For example, say a method takes in an int, I want to return that value + 1
I want the output to always be mocked as input+1 but I don't know the input at design time.

My real usage for this is with an object parameter and I need to mock to always return a new object having some of the same properties... but I do not know how to reference the parameters in the .Returns() section.

EDIT: More details:

Three types:
IMoneyConverter
Money
Currency

A Money object has two properties: decimal valueAmount and Currency valueCurrency

IMoneyConverter exposes:

.Convert(Money valueFrom, Currency currencyTo, DateTime asOfDate)

This method returns the converted Money object, in the new Currency (currencyTo) as of the specified date.

My intent is to mock the IMoneyConverter so that its .Convert method returns a new Money object having the amount of the Money (valueFrom) parameter and the Currency of the currencyTo parameter.

like image 701
Matthew Avatar asked Sep 14 '11 17:09

Matthew


2 Answers

I'm not 100% sure I understood the exact requirements, but this test works and I believe will demonstrate how to accomplish what you want:

[Test]
public void SampleTest() {
   IMoneyConverter mock = Mock.Create<IMoneyConverter>();
   mock.Arrange( x => x.Convert( Arg.IsAny<Money>(), Arg.IsAny<Currency>(), Arg.IsAny<DateTime>() ) )
      .Returns( (Func<Money,Currency,DateTime,Money>)
         ( (m, c, d ) => new Money { ValueAmount = m.ValueAmount, Currency = c }) );

   Money inMoney = new Money() { ValueAmount = 42 };
   Currency inCurrency = new Currency();
   Money outMoney = mock.Convert( inMoney, inCurrency, DateTime.Now );
   Assert.AreEqual( 42, outMoney.ValueAmount  );
   Assert.AreSame( inCurrency, outMoney.Currency );
}

public interface IMoneyConverter {
   Money Convert( Money valueFrom, Currency currencyTo, DateTime asOfDate );
}

public class Money {
   public decimal ValueAmount { get; set; }
   public Currency Currency { get; set; }
}

public class Currency {
}
like image 132
Joe Wirtley Avatar answered Oct 30 '22 21:10

Joe Wirtley


Yes, it's possible, see example.

var foo = Mock.Create<IFoo>();
Mock.Arrange(() => foo.Echo(Arg.IsAny<int>())).Returns((int i) => ++i);
like image 36
Alexandr Nikitin Avatar answered Oct 30 '22 21:10

Alexandr Nikitin