-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Different return values for same method and arguments #262
Comments
No simplier way. The library is designed to cover very corner cases that are not coverable by classic mocking libraries. So here the focus is to prefer universe to convinience. However, you can still refactor code to look more elegant, e.g. [Test]
public void TestSumRandom()
{
var randomValue1 = 7;
var randomValue2 = 8;
var fake = new Fake<Calendar>();
var sut = fake.Rewrite(f => f.SumRandom());
int randomCount = 0;
sut.Replace((Random r) => r.Next(1, 10))
.When(() => randomCount++ == 0)
.Return(randomValue1);
sut.Replace((Random r) => r.Next(1, 10))
.When(() => randomCount++ == 1)
.Return(randomValue2);
Assert.That(sut.Execute(), Is.EqualTo(randomValue1 + randomValue2));
} Looks elegant enough to me. Another way to make it better is to introduce some extensions methods on your project level. Then you get desired API and there is no need to pollute the lib's API. Although if you think that your use case is quite common and popular, you can put your suggestions and we can think about them together. |
Thank you. That looks better to me. I was considering whether to propose this library to my team, so I wanted to see what this library could and could not do. I think this is one of the common use cases. Another use case is capturing the arguments used and then grabbing the argument values later for verification. It is suitable for complex object arguments where the matcher isn't convenient. |
Could you please tell more on the second use case? Isn't it already supported? var fake = new Fake<Sut>();
var list = new List<int> { 0 };
Console.WriteLine(string.Join(", ", list));
var sut = fake.Rewrite(() => Sut.MutateArgument(list));
sut.Execute();
Console.WriteLine(string.Join(", ", list));
public class Sut
{
public static void MutateArgument(List<int> list) => list.Add(1);
}
https://dotnetfiddle.net/Ewhv4o P.S.
Yes, that's my big bad that there is no documentation. Hope to fix that this year... |
Aah, guess you meant actual arguments used in replacements, etc. They actually used to be accessible by public API some time ago. Let me think of this once again and probably expose them back. If so, it will be |
Yes. For clarity, it is something like below: using AutoFake;
namespace Test
{
public class Order
{
public IList<LineItem> Items { get; }
public Order()
{
Items = new List<LineItem>();
}
}
public class LineItem
{
public string ProductName;
public int Price;
public LineItem(string productName, int price)
{
ProductName = productName;
Price = price;
}
}
public class OrderService
{
public string CreateOrder(Order order)
{
return "100";
}
}
public class RequestHandler
{
private OrderService _orderService = new OrderService();
public string HandleRequest()
{
Order order = new Order();
order.Items.Add(new LineItem("product 1", 100));
order.Items.Add(new LineItem("product 2", 200));
return _orderService.CreateOrder(order);
}
}
public class Tests
{
[Test]
public void TestHandleRequest()
{
var fake = new Fake<RequestHandler>();
var sut = fake.Rewrite(f => f.HandleRequest());
sut.Replace((OrderService orderService) => orderService.CreateOrder(Arg.IsAny<Order>()));
sut.Execute();
// Capture the recorded "order" arguments of the calls to "OrderService.CreateOrder"
List<Order> capturedOrders = sut.Captured(() => orderService.CreateOrder(Capture.IsAny<Order>()));
Assert.That(capturedOrders.Count, Is.EqualTo(1));
Assert.That(capturedOrders.First().Items.Count, Is.EqualTo(2));
Assert.That(capturedOrders.First().Items[0].ProductName, Is.EqualTo("product 1"));
}
[Test]
public void TestHandleRequest2()
{
var fake = new Fake<RequestHandler>();
var sut = fake.Rewrite(f => f.HandleRequest());
Func<Order, bool> checkOrder = (order) => {
Assert.That(order.Items.Count, Is.EqualTo(2));
Assert.That(order.Items[0].ProductName, Is.EqualTo("product 1"));
return true;
};
sut.Replace((OrderService orderService) => orderService.CreateOrder(Arg.Is(checkOrder))).Return("1000");
sut.Execute();
}
}
} The method |
This is achievable and I'd say convenient enough because you can always write extensions but this might stop working if |
Unfortunately, I still don't see something better than exposing |
I see, thanks. Please feel free to close this issue. |
If a method is called multiple times with the same arguments, how to let different calls return different values?
For example, let's say I have a class:
I want the 1st call to
r.Next(1, 10)
returns 7 and the 2nd call returns 8.One of the way I found is like below:
But it's a little tedious. Is there a simpler way to achieve it?
The text was updated successfully, but these errors were encountered: