Skip to content
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

Update existing mock using Expression #293

Closed
soringp opened this issue Oct 6, 2016 · 9 comments
Closed

Update existing mock using Expression #293

soringp opened this issue Oct 6, 2016 · 9 comments

Comments

@soringp
Copy link

soringp commented Oct 6, 2016

Hi, I'm trying to use Linq to Mocks to update an existing mock, in the same way I use it to create the mock:

Expression<Func<IClaimContext, bool>> initialSetup = cc => cc.GetClaim() == new Claim(123);

var claimContext = Mock.Of<IClaimContext>(initialSetup);

Assert.AreEqual(123, claimContext.GetClaim().ClaimId);


Expression<Func<IClaimContext, bool>> updateSetup = cc => cc.GetClaim() == new Claim(321);

var mock = Mock.Get(claimContext);

// TO DO: Pass updateSetup to mock...

Assert.AreEqual(321, claimContext.GetClaim().ClaimId);

How should I write the missing code to use "updateSetup" so that my second assert passes?

It works with this, instead of using the expression,

mock.Setup(cc => cc.GetClaim()).Returns(new Claim(321));

but if I have multiple setups the code would look much better with Linq to Mocks, and I want to pass the expression as a parameter.

Thanks

@kzu
Copy link
Contributor

kzu commented Oct 11, 2016

I think defining what it means to update can get quite tricky really fast, and expectations will fall short all over. For example, are you intending to replace all method calls or are you going to match by parameters too and only replace those that match with the update expression?

I agree the feature looks interesting. Something like mock.Update(expression)...

@soringp
Copy link
Author

soringp commented Oct 13, 2016

An Update method that gets an expression and changes the returned value for matched parameters would be nice. It should do the the same thing as mock.Setup().Returns(), but in a compact way.
It's actually a setup, but Setup already has a signature what gets an expression, but does something else.

@stakx
Copy link
Contributor

stakx commented Sep 23, 2017

@soringp: I agree that the update expression should be treated & have the same effect as several combined Setups.

I'd like to bring up one additional point. Like @davidshen84 suggested in #229, this is obviously a convenience feature (it doesn't do anything that Moq can't already do some other way, but it does it in a more compact way), therefore it should be convenient to use. Given that Mock.Of<T> doesn't return a Mock on which you could immediately call mock.Update, it should be possible to call Update without having to go through Mock.Get first. Therefore I propose that the new method be made static, i.e.:

partial class Mock
{
    public static void Update<T>(T mocked, Expression<Func<T, bool>> updateExpression);
}

Any opinions on this?

@stakx
Copy link
Contributor

stakx commented Oct 14, 2017

Is anyone still interested in this feature at all?

@soringp
Copy link
Author

soringp commented Oct 14, 2017

@stakx Sorry for the delay, but yes, I'm still interested in this feature and I like the proposed method.

As a side note, I like compact code and this proposed Update will look very nice, but I have some reservations regarding the expression syntax. For the untrained eye it looks a bit dodgy. Too bad we cannot replace == with a more meaningful operator.

If you add this method I think I will also add a local extension to update the mock:

public static void Update<T>(this Mock<T> mock, Expression<Func<T, bool>> expression) where T:class
{
     Mock.Update(mock.Object, expression);
}

Thanks for your interest in this.

@stakx
Copy link
Contributor

stakx commented Oct 22, 2017

Too bad we cannot replace == with a more meaningful operator.

It is indeed too late for that kind of change. But I'm curious, which operator would've been more meaningful in your opinion, and why?

@soringp
Copy link
Author

soringp commented Oct 22, 2017

The assignment operator or the lambda operator could have been good alternatives but the first is not allowed in expressions and I don't see how you could use the latter without some language changes.

It was just a silly idea, only equals works. I guess I was thinking more of using an alias or a custom operator, but this is not possible with C# so case closed :)

@Arithmomaniac
Copy link

I think I would name the method SetupSo (SetupSuchThat?). That would emphasize that the expression is what you want to happen to your mock.

@stakx
Copy link
Contributor

stakx commented Jul 13, 2018

Closing this dormant issue, but marking it as "unresolved" so it can be easily found again. Please see #642 for details. If you'd like to pick this up and work on it, please post here briefly and we'll see what we can do!

@stakx stakx closed this as completed Jul 13, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants