开发者

Moq and Code Contracts

When using class invariants, Code contracts seems to inject code everywhere. Stuff like this

[ContractClassFor(typeof(IX))]
interface IXContract开发者_JAVA百科  
{  
    [ClassInvariant]
    void Invariant() { ... }
}

[ContractClass(typeof(IXContract))]
interface IX { event EventHandler b; }

var a = new Mock<IX>();

a.Raise(x => x.b += null);

Fails with an error message

Could not locate event for attach or detach method Void $InvariantMethod$().

Anyone know of a solution?


This unit test "passes" when run without generating exceptions:

[ContractClassFor(typeof(IX))]
class IXContract
{
    [ContractInvariantMethod]
    void Invariant() { }
}

[ContractClass(typeof(IXContract))]
public interface IX { event EventHandler b; }

/// <summary>
/// Summary description for UnitTest1
/// </summary>
[TestClass]
public class UnitTest1
{
    public void MyTest()
    {
        var a = new Mock<IX>();

        a.Raise(x => x.b += null);
    }
}

I'm not entirely sure what's going on and how you're compiling (or transcribing) the above, but I don't think you can have "ContractClassFor" attribute decorating an interface, and you certainly can't have the implementation "{ ... }" in an interface. You also need to make your interface IX public to mock it (or else internal with InternalsVisibleTo() castle proxy in your properties).

Hopefully this helps, but feel free to update your post with new code if this doesn't lead you toward what you're looking to do.


Your code is incorrect. It should look like this:

[ContractClassFor(typeof(IX))] 
internal abstract class XContract : IX
{   
    // Invariants belong on your actual implemenation; interfaces don't dictate implemenation so this isn't appropariate here.
    // [ ContractInvariantMethod] 
    // void Invariant() { ... } 

    public event EventHandler b { get { return default(EventHandler); } set { }}
} 

[ContractClass(typeof(XContract))] 
interface IX { event EventHandler b; } 

var a = new Mock<IX>(); 

a.Raise(x => x.b += null); 

Notice that the Contract class is Internal Abstract, and that it also now implements your interface. The Invariant isn't appropiate there, as that's for implemenation details; you don't know how people will implemenent your interface, so don't put it there. Also the attribute for invariant methods is ContractInvariantMethodAttribute.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜