使用类不变量时,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$().
有人知道解决方案吗?
答案 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
。