当前位置: 首页 > 编程语言 > C#

unit testing仅在构建服务器上运行时失败分享

时间:2023-04-10 12:59:18 C#

C#学习教程:仅在构建服务器上运行时单元测试失败现在。publicstaticclassSystemTime{#region静态字段publicstaticFuncNow=()=>DateTime.Now;#endregion}以下是在xunitunit测试中使用它的示例:[事实]publicvoidit_should_update_the_last_accessed_timestamp_on_an_entry(){//安排varservice=this.CreateClassUnderTest();varexpectedTimestamp=SystemTime.Now();SystemTime.Now=()=>expectedTimestamp;//执行service.UpdateLastAccessedTimestamp(this._testEntry);//断言Assert.Equal(expectedTimestamp,this._testEntry.LastAccessedOn);测试在本地运行良好,但在我们的构建服务器上失败,因为Assert语句中的日期时间不同。考虑到DateTime是通过上面提到的委托包装器模拟的,我很难想出它会失败的原因。我已经验证UpdateLastAccessedTimestamp方法的实现没有问题,并且测试在本地运行时通过。不幸的是,我无法在我们的构建服务器上调试它。任何想法为什么它只在构建服务器上运行时失败?请注意,UpdateLastAccessedTimestamp的实现方式如下:publicvoidUpdateLastAccessedTimestamp(Entryentry){entry.LastAccessedOn=SystemTime.Now();this._unitOfWork.Entries.Update(条目);this._unitOfWork.Save();}Entry类只是一个简单的POCO类,它有很多字段,包括LastAccessedOn字段:publicclassEntry{publicDateTimeLastAccessedOn{get;放;}//为保持示例简洁而遗漏的其他字段}您的问题可能是由于使用静态SystemTime多个单元测试。如果你有eg:unittesting1[Fact]publicvoidit_should_update_the_last_accessed_timestamp_on_an_entry(){//安排varservice=this.CreateClassUnderTest();varexpectedTimestamp=SystemTime.Now();SystemTime.Now=()=>expectedTimestamp;//执行service.UpdateLastAccessedTimestamp(this._testEntry);//断言Assert.Equal(expectedTimestamp,this._testEntry.LastAccessedOn);}publicvoidUpdateLastAccessedTimestamp(Entryentry){entry.LastAccessedOn=SystemTime.Now();这个._unitOfWork.Entries。更新(条目);this._unitOfWork.Save();}unittesting2[Fact]publicvoiddo_something_different{SystemTime.Now=()=>DateTime.Now;因此,我们假设单元测试2(已完成)在单元测试2中在测试1中的行之间触发:SystemTime.Now=()=>expectedTimestamp;//单元测试2从这里开始执行//Actservice.UpdateLastAccessedTimestamp(this._testEntry);如果发生这种情况,UpdateLastAccessedTimestamp将不会(必然)使用您在SystemTime.Now=()=>expectedTimestamp;中设置的预期日期时间值;SystemTime.Now=()=>预期时间戳;因为另一个测试已经覆盖了您从单元测试1提供的功能这就是为什么我认为您最好将DateTime作为参数传递,或者像这样使用可注入的日期时间://////可注入的DateTime接口,应该用于确保特定于日期的逻辑更易于测试///publicinterfaceIDateTime{/////当前数据时间///DateTimeNow{get;}}//////DateTime.Now-用作具体实现///publicclassSystemDateTime:IDateTime{//////DateTime.Now///publicDateTimeNow{get{returnDateTime.Now;}}}//////DateTime-用于围绕DateTime.Now进行单元测试功能(外部化对DateTime.Now的依赖///publicclassMockSystemDateTime:IDateTime{privatereadonlyDateTimeMockedDateTime;//////接受模拟用于测试的DateTime//////publicMockSystemDateTime(DateTimemockedDateTime){this.MockedDateTime=mockedDateTime;}//////从构造函数传递的DateTime//publicDateTimeNow{get{returnMockedDateTime;}}}使用此方案,您的服务类可能会更改(类似于):publicclassService{publicService(){}publicvoidUpdateLastAccessedTimestamp(Entryentry){entry.LastAccessedOn=SystemTime.Now();this._unitOfWork.Entries.Update(条目);this._unitOfWork.Save();}}为此:publicclassService{privatereadonlyIDateTime_iDateTime;公共服务(IDateTimeiDateTime){如果(iDateTime==null)抛出新的ArgumentNullException(nameof(iDateTime));//或者如果没有提供_iDateTime=iDateTime;你可以更新SystemDateTime的具体实现}publicvoidUpdateLastAccessedTimestamp(Entryentry){entry.LastAccessedOn=_iDateTime.Now;this._unitOfWork.Entries.Update(条目);this._unitOfWork.Save();您可能不熟悉服务的实际实现(或使用IOC容器):Serviceservice=newService(newSystemDateTime());对于测试,您可以使用模拟框架或使用Mock类:Serviceservice=newService(newMockDateTime(newDateTime(2000,1,1)));你的单元测试可能变成:[Fact]publicvoidit_should_update_the_last_accessed_timestamp_on_an_entry(){//ArrangeMockDateTimemockDateTime=newMockDateTime(新日期时间2000,1,1);varservice=this.CreateClassUnderTest(mockDateTime);//执行service.UpdateLastAccessedTimestamp(this._testEntry);//断言Assert.Equal(mockDateTime.Now,this._testEntry.LastAccessedOn);你很幸运,它在本地工作要让它工作,你必须存根服务获取其最后访问数据时间的位置,并检查返回时间。此时,本地机器的速度足以在DataTime.Now上同时返回2个时间,而构建服务器则不然。以上就是C#学习教程的全部内容:只在构建服务器上运行时单元测试失败。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文来自网络收藏,不代表立场,如涉及侵权,请点击右边联系管理员删除。如需转载请注明出处: