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

Add support for code contracts #94

Closed
alexsimply opened this issue Feb 17, 2014 · 5 comments
Closed

Add support for code contracts #94

alexsimply opened this issue Feb 17, 2014 · 5 comments
Labels

Comments

@alexsimply
Copy link
Contributor

At the moment, Moq offers no support for Code Contracts, which is included in C# 4.0.

While we can disable code contracts on test assemblies, contracts often provide very useful information about the external facing requirements of our libraries, so this is a less-than-ideal solution.

The workaround to this is to include intermediary assumptions about the library. This is highly verbose, and completely clutters up any tests using code contracts.

Entity mock = Mock.Of<Entity>();
Contract.Assume(mock != null);
entityUser.use(mock);

For anything that requires a non-null object by contract, we would need to explicitly specify an assumption about the output of the Moq library. This requires a huge amount of extra intermediary code, at least one assumption for every mock.

The best alternative is to include code contract information in the Moq library itself, which would provide clear guarantees as to the preconditions and postconditions of the Moq API.

It's worth noting that this is likely worth doing in and of itself as code contracts can add a great degree of robustness to an existing library.

@alexsimply
Copy link
Contributor Author

See this pull request for a quick implementation that adds basic compatibility with Code Contracts.

@kzu
Copy link
Member

kzu commented Feb 20, 2014

Does this build on SL or do we have conditionals in place?

@varon
Copy link

varon commented Feb 21, 2014

Code Contracts should be fully support on the Silverlight platform. It compiles.

@kzu
Copy link
Member

kzu commented Aug 5, 2014

This doesn't compile or work on v3.5.

I'm reverting this change until that's figured out.

Thanks.

@stakx
Copy link
Contributor

stakx commented Jun 10, 2017

It would seem that since Moq no longer targets .NET 3.5 at all, that roadblock would be out of the way.

First, let me admit that while I've played around with Code Contracts it a few times over the years, I am not deeply familiar with it.

That being said, I fail to see how sprinkling a few Contract.Requires and Contract.Ensures is going to benefit any consumers of Moq.dll. Unless Moq is compiled with a CONTRACTS_FULL preprocessor symbol defined, those are simply stripped out by the compiler. And if Moq is compiled with CONTRACTS_FULL, then those method calls in the produced binary are going to produce runtime assertion errors unless Moq.dll is rewritten with ccrewrite as a post-compilation step. (Which also means that the Code Contracts tools need to be installed on all build machines, including the CI server.)

As far as I understand it, ccrewrite will perform static analysis on the Moq code base itself, based on the added contract blocks. If static analysis doesn't find any problems, the contract methods are removed. So again, we would end up with a Moq.dll without any embedded Code Contracts information that would be useful to the consumer. Code Contracts would only have been useful to Moq's own code base.

The once possible option I can see is to factor out the contract blocks into separate contract classes ([ContractClassFor(…)]) and not run ccrewrite on Moq.dll. Not sure whether this would be possible in all cases, such as for static methods like Mock.Of<T>.

Finally, and this is perhaps the final nail in the coffin, according to microsoft/CodeContracts#409 ("What does the Future of Code Contracts Look Like?"), development on Code Contracts has more or less ceased and it apparently isn't supported on .NET Core.

I will happily stand corrected if I have misunderstood anything in this issue or in the PR referred above (#95). Until that happens, I don't see how adding Code Contracts contract blocks would benefit Moq or its consumers, so I'm closing this issue for the time being.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants