Moq和代码合同

时间:2011-06-17 18:46:22

标签: c# moq code-contracts

使用类不变量时,Code契约似乎在任何地方都会引入代码。像这样的东西

[ContractClassFor(typeof(IX))]
interface IXContract  
{  
    [ClassInvariant]
    void Invariant() { ... }
}

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

var a = new Mock<IX>();

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

失败并显示错误消息

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

有人知道解决方案吗?

2 个答案:

答案 0 :(得分:3)

此单元测试在运行时“通过”而不会产生异常:

[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);
    }
}

我不完全确定发生了什么,以及你如何编译(或转录)上述内容,但我认为你不能将“ContractClassFor”属性装饰一个接口,你当然不能拥有在接口中实现“{...}”。您还需要将您的界面IX公开以模拟它(或者在您的属性中使用InternalsVisibleTo()城堡代理内部)。

希望这会有所帮助,但如果这不能引导您实现您的目标,请随时使用新代码更新您的帖子。

答案 1 :(得分:2)

您的代码不正确。它应该是这样的:

[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); 

请注意,Contract类是Internal Abstract,它现在也实现了您的接口。 Invariant不适合那里,因为那是实施细节;你不知道人们将如何实现你的界面,所以不要把它放在那里。此外,不变方法的属性为ContractInvariantMethodAttribute