Is it possible to add Returns<T>(T[] values) support for NSubstitute?
Idea discussed in the question here and @dtchepak's answer:
https://stackoverflow.com/q/50162109/906
(EDIT by @dtchepak 20180507: linked to question instead of my answer and comments)
Hi @zvirja and @alexandrnikitin,
From the SO question:
[TestCase(new[]{2, 2, 3, 1, 5}, Category.Yahtzee, 0)]
public void AddPoints_ForGivenCategory_PointsAreStored(
int[] rollResults, Category selectedCategory, int expectedScore)
{
_randomizer.GetRandomNumber(MIN_VALUE, MAX_VALUE).Returns(rollResults); //<-rollResults not allowed
IDice[] dice = MakeNewDiceSet();
_game.NewGame("A");
_game.RollDice(dice);
_game.AddPoints(selectedCategory);
var result = _game.GameStatus().First()[selectedCategory];
Assert.AreEqual(expectedScore, result);
}
The current restriction on Returns requiring at least one value means this does not compile.
I'd appreciate your thoughts on this. Please consider it before looking at my comments on the SO post so I don't bias you. 馃槃
As I see, it's not only about restrictions on number of elements (that can be done via a check inside) but extension methods signature inference. Imagine the following case:
interface IFoo
{
object GetObj();
}
var sub = Substitute.For<IFoo>();
sub.GetObj().Returns(new [] {new object(), new object()}); //should it return the array or the objects one by one?
It can be solved via a dedicated method like ReturnsMany() that accepts arrays and IEnumerables. That extension methods can be introduced inside the test project easily but I'm not sure it's worth to add it to the NSub library.
@mehlian Thank you for the idea, but due to few reasons we won't proceed with this. At least for now. I see the following ones:
Returns<T>(T[] values) looks appealing but it's not possible to support due to compile problem (see previous comment).ReturnsMany<T>(T[] values) looks OKish but it means a second way to set a return sequence. I doubt we dare to deprecate the current one. Ambiguity is always bad. If you really want to have that nice syntax then what I can suggest is to introduce an extension method in your test project that calls Returns<T>(T returnThis, params T[] returnThese) under the hood.
Most helpful comment
@mehlian Thank you for the idea, but due to few reasons we won't proceed with this. At least for now. I see the following ones:
Returns<T>(T[] values)looks appealing but it's not possible to support due to compile problem (see previous comment).ReturnsMany<T>(T[] values)looks OKish but it means a second way to set a return sequence. I doubt we dare to deprecate the current one. Ambiguity is always bad.If you really want to have that nice syntax then what I can suggest is to introduce an extension method in your test project that calls
Returns<T>(T returnThis, params T[] returnThese)under the hood.