Comments (5)
This would be super valuable... with BDD-style testing, I often have to use Verify
and I am only asserting a few values match an expression on a complex object. Right now, it's not easy (read: impossible?) to figure out what values in the expression didn't match without debugging.
Example:
_context.MailNotifier.Verify(
x => x.SendNotification(It.Is<NotificationViewModel>(n =>
n.Username == currentUser.Username &&
n.IsOptional)), Times.Once);
Either expression could be false and I won't know which. This is a simple example, when I do things like "StartsWith(str)" it becomes even more annoying to figure out why it failed.
I mention BDD-style specifically Setup
calls are separated from Verify
calls, sometimes between classes, so I can't use Callback
easily to capture args (also that feels smelly). I'm using SpecFlow as my BDD framework, for example.
what I want
What I want is what I can do in Jest projects (pseudo code equivalent of above):
expect(_context.mailNotifier.sendNotification).toHaveBeenCalledWith(expect.objectContaining({
username: currentUser.username,
isOptional: true
});
When this expectation fails, Jest gives me a full diff of the properties I was comparing.
Perhaps for Moq, another similar API could allow the same thing?
_context.MailNotifier.Verify(
x => x.SendNotification(It.IsObjectContaining<NotificationViewModel>()
.Where(n => n.Username, Is.EqualTo(currentUser.Username)
.Where(n => n.IsOptional, Is.True)
)
), Times.Once);
This has the added benefit of reusing existing Is.(...)
API 👍
from moq4.
I think that for objects you have a nice workaround most of the times, which is to override ToString()
. But if you do not have control over the class, this would be nice to have. You have to take into account the possible length of the resulting string, and also circular references if you recursively print property values. Not trivial at all!
Also interesting for enhancing reporting is when you have array parameters, which is specially useful for params
methods. Also in-memory collections such as Dictionary
, List
and Collection
. I'd not recommend to implement it for IEnumerable
or other interfaces because you could have a huge (or even infinite) sequence there. The same caveats about the length of the resulting string and circular references apply.
from moq4.
I think this idea has a lot of potential. But I don't think it would be good to decide on one fixed way of reporting additional object data, because of the problems this could cause (see @icalvo's post above).
I would suggest that this new functionality be exposed in a slightly more general way. For example, a new public contract could be introduced, say:
namespace Moq.Diagnostics
{
public interface IObjectFormatter
{
string Format(object obj);
}
}
Exactly one instance of this new interface type could then be registered on a Mock
or MockRepository
. This would then be used in messages to (you guessed it) create a string representing a specific object. Such a string could consist only of the type name, but it could also include the property names and values of an object, or the first n items of a sequence, etc.
By default, Moq would be using a DefaultObjectFormatter
implementation that produces the exact same output as Moq does today.
If the questions raised in the post above can be solved such that the resulting formatting would work well for most objects, Moq could ship with one (or several) additional concrete implementations in the new Moq.Diagnostics
namespace that people could use to quickly switch over to more advanced error reporting.
from moq4.
Closing this issue due to inactivity. It also belatedly occurred to me that it wouldn't be straightforward to figure out when to use an object's .ToString()
and when to perform extended formatting. Implementing this feature could easily lead to simple types such as decimal
or DateTime
be formatted as objects, which might be unexpected.
from moq4.
Implementing this feature could easily lead to simple types such as decimal or DateTime be formatted as objects, which might be unexpected.
Well, an easy workaround would be to ignore all IFormattable
for this feature, which is not precise, but might be enough in practice.
But even if we don't, that would just provide some extra information for those:
Expected invocation on the mock at least once, but was never performed:
r => r.SetDate(It.Is<DateTime>(d => d.Ticks == 12345))
No setups configured.
Performed invocations:
Something.SetDate(11/21/2017 8:00:11 PM { Ticks = 636468912254430306 })
from moq4.
Related Issues (20)
- Exception throw in dotnet8 (working in dotnet6) HOT 2
- VerifySet throws TargetInvocationException when constructer refers to itself
- Add ability for asynchronously waiting for an invocation
- Moq library throwing TypeIniatilizationException. HOT 1
- Request: Ability to setup a property of type Task<ConcreteType> by mocking interface
- Supporting .NET8 HOT 2
- Mock.Protected().Verify fails sometimes
- Moq "set" matcher fails when setting StringValues with string HOT 1
- It.IsAny<StructObject>() isn't
- Documentation Unavailable Online HOT 2
- Consider adding IgnoresAccessChecksTo("Unsupported")
- Explicit support for matching cancellation tokens with It class. (It.IsCancellationToken())
- Moq Setup does not work with "object" as generic type? HOT 1
- IVerifies.Verifiable* documentation comments errata?
- Support for post-invocation callbacks on void methods?
- Semantic error in unit test MatchesIsNotInEnumerable()?
- Documentation link is broken HOT 8
- Constructing Mock<DerivedControl>.Object throws TypeLoadException HOT 2
- How do you Verify an IAsyncEnumerable<T> ?
- Add Way to Exclude Calls from VerifyNoOtherCalls HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from moq4.