C# 为什么这两个集合不相等?
在使用XUnit编写一些单元之前,我遇到了一些令人惊讶的事情:C# 为什么这两个集合不相等?,c#,f#,xunit,C#,F#,Xunit,在使用XUnit编写一些单元之前,我遇到了一些令人惊讶的事情: let id=Guid.Empty 让联系人={ 姓名={ FirstName=“Marcel” 初始值=无 LastName=“Patulacci” } DateOfBith=新的日期时间(1850,12,25) 地址={ Address1=“41 av 8 Mai 1945” 地址2=无 City=“Sarcelles” 状态=无 Zip=“95200” } 电话号码={ 拨号代码=33 LocalNumber=“7660307
let id=Guid.Empty
让联系人={
姓名={
FirstName=“Marcel”
初始值=无
LastName=“Patulacci”
}
DateOfBith=新的日期时间(1850,12,25)
地址={
Address1=“41 av 8 Mai 1945”
地址2=无
City=“Sarcelles”
状态=无
Zip=“95200”
}
电话号码={
拨号代码=33
LocalNumber=“766030703”
}
Email=“马塞尔。patulacci@outlook.com"
}
[]
让``开户……`()=
让event=event.AccountOpened({
AccountId=id
接触
})
设a=[事件]
设b=seq{yield event}
断言相等(a,b)
System.NullReferenceException
:对象引用未设置为对象的实例
考虑到Assert
使用的重载是:
public static void Equal(预期为IEnumerable,实际为IEnumerable)
其中指出:
使用默认比较器验证两个序列是否相等
为什么认为它们不同,为什么断言.Equal
引发系统.NullReferenceException
[编辑]
System.NullReferenceException
:对象引用未设置为对象的实例。
在Domain.Events.AccountOpenedEvent.Equals(objectobj,IEqualityComparer comp)
在Domain.Events.Event.Equals(objectobj,IEqualityComparer comp)
似乎
键入PersonalName={
名字:字符串;
MiddleInitial:字符串选项;
LastName:string;
}
类型地址={
地址1:字符串;
地址2:字符串选项;
城市:字符串;
状态:字符串选项;
拉链:细绳;
}
类型电话号码={
拨号代码:int;
LocalNumber:string
}
类型联系人={
姓名:个人姓名;
DateOfBith:DateTime
电子邮件:字符串;
地址:地址;
电话号码:电话号码
}
类型AccountOpenedEvent={
帐户ID:Guid
联系人:联系人
}
类型事件=
|AccountOpenedEvent的AccountOpened
事实证明,
event
的其中一个字段是null
,而不是event
本身。问题存在于测试的正上方定义的id
和contact
:
let id=Guid.Empty
让联系人={
姓名={
FirstName=“Marcel”
初始值=无
LastName=“Patulacci”
}
DateOfBith=新的日期时间(1850,12,25)
地址={
Address1=“41 av 8 Mai 1945”
地址2=无
City=“Sarcelles”
状态=无
Zip=“95200”
}
电话号码={
拨号代码=33
LocalNumber=“766030703”
}
Email=“马塞尔。patulacci@outlook.com"
}
[]
让``开户……`()=
让event=event.AccountOpened({
AccountId=id
接触
})
设a=[事件]
设b=seq{yield event}
断言相等(a,b)
问题是当独立运行测试时,id
和contact
没有初始化,因此即使事件
不是null
,contact也是null
(id
是Guid
又称为struct
它仍然有一个值)
由于F#与结构相等一起工作,如果其中一个字段未初始化,则有一个字段null
足以使Assert
在其实现的某个点失败
有几种解决方案/变通方法:
让getId()=Guid.Empty
让getContact()={
姓名={
FirstName=“Marcel”
初始值=无
LastName=“Patulacci”
}
DateOfBith=新的日期时间(1850,12,25)
地址={
Address1=“41 av 8 Mai 1945”
地址2=无
City=“Sarcelles”
状态=无
Zip=“95200”
}
电话号码={
拨号代码=33
LocalNumber=“766030703”
}
Email=“马塞尔。patulacci@outlook.com"
}
[]
让``开户……`()=
让id=getId()
let contact=getContact()
让event=event.AccountOpened({
AccountId=id
接触
})
设a=[事件]
设b=seq{yield event}
断言相等(a,b)
虽然这些变通方法可行,但我感到惊讶的是,当测试运行/未初始化时,单元测试函数正上方声明的变量没有被考虑
也许值得再问一个问题,为什么会这样。
这在某种意义上是令人惊讶的,如果一个函数可以被定义并返回与这些变量几乎相同的东西,这意味着let也被正确编译,那么为什么变量不是这样呢?你确定
事件
不是空值吗?我敢打赌Assert.Equal
是用类似actual.Equals(预期)
的东西实现的,如果actual
为null,则会抛出。不是这样,我在Assert.Equal
中设置了一个断点,在那个阶段,两个参数都是非null的。请添加完整的示例和完整的异常消息。可能空引用异常不是来自您提供的测试?您声称,Assert.Equal
正在引发异常,但它不可能引发异常。这些陈述中只有一个是正确的。@DanWilson“但是它不可能抛出异常”我没有声明。@DanWilson你可以检查我的答案