-
Notifications
You must be signed in to change notification settings - Fork 179
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
Repeated class is misleading #808
Comments
It never really bothered me, but I see how it can be confusing... Another option would be something like Anyway, changing this would be a breaking change; even though we're not strictly against introducing breaking changes, we usually try to avoid the ones that would affect many users. @FakeItEasy/owners how do you feel about this? |
Hi, @jholovacs. Thanks for your interest. As a native speaker of English, and raging pedant, I agree that it's not technically correct, and that if we were implementing the functionality afresh, a different name would probably be better. On the other hand the interpretation could be a little bit in the ear of the beholder, and I doubt many people interpret As @thomaslevesque says, the change would be a breaking one. I'm sure there are scores of people happily using the class as it is, who would all of a sudden have to rewrite their tests for what seems like minimal gain to me. And Mr. Levesque's suggestion of a public class Executed
{
public static IRepeatSpecification Exactly { get { return Repeated.Exactly; } }
}
public interface IFoo
{
void FooIt();
}
void Main()
{
var fake = A.Fake<IFoo>();
A.CallTo(() => fake.FooIt()).MustHaveHappened(Executed.Exactly.Once);
} Or you could even add an extension method to enable this syntax: A.CallTo(() => fake.Add(A<object>._))
.MustHaveHappened(2.Times()); The possibilities are many. |
This conversation was had before (I'm afraid I can't remember where, it may have been JabbR). IIRC the conclusion was along the lines of "yes it's not perfect", "no it's not worth changing". That said, we could backlog this as a breaking change and consider it if/when we are planning a new major. Whilst it reads beautifully, I'd be against adding extension methods to primitive types to allow |
It could also be done in a minor release if we deprecated |
Oh, yeah. That's for end users who really like it and don't mind the tradeoff of the extension method on Although I missed another option in that thread:
which doesn't require an extension on If anyone's interested, both extension methods that I discuss can be found at https://gist.github.com/blairconrad/c83f0e6756879d6c8f25 (although they're 2 years old, so may need freshening)
Adding If we were going to change the syntax at all, I'd push to look at seeing how we could unify this repeat specification with those of Limited Call Specifications. Not that I'm saying we should. Just if we wanted to make a change at all. |
I personally like the idea of deprecating Repeated, but I admit I'm biased. I could also see having |
All: I continue to think that it's not worth making a change unless we bring more benefits than originally proposed. I've been thinking about the two kinds of "repeat" that we have, and here's what I've come up with: First,
The last 3 can all have these tacked on the end:
For limited calls specs, we just have
Some examples: A.CallTo(()=>f.Boo()).MustHaveHappened(Repeated.Like(n => n % 2 == 0));
A.CallTo(()=>f.Boo()).MustHaveHappened(Repeated.Exactly.Once);
A.CallTo(()=>f.Boo()).MustHaveHappened(Repeated.NoMoreThan.Once);
A.CallTo(()=>f.Boo()).MustHaveHappened(Repeated.AtLeast.Once);
A.CallTo(()=>f.Boo()).MustHaveHappened(Repeated.Exactly.Times(3));
A.CallTo(()=>f.Boo()).Returns("yeek").NumberOfTimes(3); Immediate thoughts, aside from the amibguity of
An alternative to A.CallTo(()=>f.Boo()).Returns("yeek").AtMost(3).Times; And for the A.CallTo(()=>f.Boo()).MustHaveHappened().ANumberOfTimesMatching(n => n % 2 == 0));
A.CallTo(()=>f.Boo()).MustHaveHappened().AtLeast().Once; // AtLeastOnce?
A.CallTo(()=>f.Boo()).MustHaveHappened().AtLeast(3).Times;
A.CallTo(()=>f.Boo()).MustHaveHappened().AtMost(3).Times;
A.CallTo(()=>f.Boo()).MustHaveHappened().Exactly().Once; // ExactlyOnce?
A.CallTo(()=>f.Boo()).MustHaveHappened().Exactly(3).Times; We probably want to keep Oh. I should mention that any A.CallTo(() => fake.Bar(1)).MustHaveHappened().Exactly(3).Times
.Then(A.CallTo(() => fake.Bar(2)).MustHaveHappened(); Which may complicate the implementation a bit. I suppose the same could be said of @thomaslevesque's #804. I'm still betting on an achievable interface, but I'm keen to hear your overall thoughts—about my resistance to the Thanks. |
Defaulting to P2 |
The |
Overall, this seems like a lot of work, and risk, for little gain. I'm removing |
I agree. Me, I'd keep everything as is. |
👍 |
It seems all the @FakeItEasy/owners feel the same way, so I'm closing the issue. @jholovacs thanks for raising this and initiating the discussion. I hope you understand why we're closing the discussion. If you feel strongly that we are making the wrong decision here, please feel free to speak up. |
Well I still think it's confusing, and the reason I brought it up is On Aug 19, 2016 12:00 PM, "Adam Ralph" notifications@github.com wrote:
|
I guess we could still consider a direct replacement for @FakeItEasy/owners thoughts? |
I don't mind the idea, but |
If we're interested in making a change for this issue, we should consider moving now that we're (I hope) nearing the end of the 3.0.0 pre-release phase. If we're not, I think we should close it. And I think we should close it.
Like @thomaslevesque, I don't like the sound of |
I don't think we should change anything. |
I hate to rehash a ticket that's been commented on and has a decision made on it, but from where I'm sitting, that As committers, perhaps you have a biased viewpoint of API usability issues like this as you're used to the wrinkles in the API? For what it's worth in a survey of 7 random devs at my firm who use FakeItEasy, literally all of them think this is confusing and should be fixed. How about the alternative of |
@herebebeasties, thanks for the comment. We understand your concerns and appreciate having such a passionate community. Sadly, I don't think there's anything new in your argument: changing the API would cause an inconvenience for many many existing users, and the proposed alternative just isn't compelling enough: This doesn't mean that we're against any change; we're just not willing to make a sweeping change for what we perceive to be sufficient benefit. |
@thomaslevesque points out that this makes no sense:
of course, I meant
|
@thomaslevesque and I went off and chatted about possible replacements for MustHaveHappened() // as today
MustNotHaveHappened() // as today
MustHaveHappenedOnceExactly()
MustHaveHappenedTwiceExactly()
MustHaveHappened(3, Times.Exactly)
MustHaveHappened(3, Times.OrMore)
MustHaveHappened(3, Times.OrLess)
MustHaveHappenedANumberOfTimesMatching(n => n %2 == 0)
MustHaveHappenedANumberOfTimesMatching(IsPrime) // where `IsPrime` is a method group
We like this approach because
And we can also supply a soft transition: the Accordingly, I'm reopening the issue. Comments welcome. |
I'd drop this. It's not supported now, and wouldn't produce good failure messages anyhow. If a call to a helper predicate is needed, we should rely on MustHaveHappenedANumberOfTimesMatching(n => IsPrime(n)) |
Makes sense to me! |
There's been no objection in nearly a week, so as suggested above, I've created #1292 to track the actual software change. |
A verification of
IReturnValueArgumentValidationConfiguration<T>.MustHaveHappened(Repeated.Exactly.Once)
in the English language, this means that the call must have happened twice; once, then repeated exactly once.
Recommend changing the name of this Repeated class to Executed or something so there's no confusion.
The text was updated successfully, but these errors were encountered: