C# 单元测试和模拟域对象
我有一个域类,如下所示:C# 单元测试和模拟域对象,c#,unit-testing,C#,Unit Testing,我有一个域类,如下所示: public class Employee { public Guid EmployeeId { get; private set; } public string Name { get; private set; } public string Surname { get; private set; } ... // other properties public ICollection<Language>
public class Employee
{
public Guid EmployeeId { get; private set; }
public string Name { get; private set; }
public string Surname { get; private set; }
...
// other properties
public ICollection<Language> Languages { get; private set; }
= new List<Language>();
public ICollection<Skill> Skills { get; private set; }
= new List<Skill>();
public void AddLanguage(Language language)
{
if (language == null)
return;
Languages.Add(language);
}
public void DeleteLanguage(Guid languageId)
{
var languageToDelete = Languages
.SingleOrDefault(x => x.LanguageId == languageId);
if(languageToDelete == null)
throw new ArgumentException("Language entry doesn't exist.");
Languages.Remove(languageToDelete);
}
}
公共类员工
{
公共Guid EmployeeId{get;private set;}
公共字符串名称{get;private set;}
公共字符串姓氏{get;private set;}
...
//其他属性
公共ICollection语言{get;private set;}
=新列表();
公共ICollection技能{get;private set;}
=新列表();
公共语言(语言)
{
if(语言==null)
返回;
语言。添加(语言);
}
公共语言(Guid languageId)
{
var languageToDelete=语言
.SingleOrDefault(x=>x.LanguageId==LanguageId);
if(languageToDelete==null)
抛出新ArgumentException(“语言条目不存在”);
语言。删除(languageToDelete);
}
}
我想测试给定的方法,但我被卡住了
我有:
[Fact]
public void AddLanguage_AfterCallWithValidObject_LanguagesCollectionContainsAddedObject()
{
var language = new Mock<Language>();
var employee = new Employee("Name", "Surname", ...);
employee.AddLanguage(language.Object);
Assert.Contains(employee.EmployeeLanguages, x => x.Language.Equals(language.Object));
}
[Fact]
public void DeleteLanguage_WhenLanguageWithGivenIdDoesntExist_ThrowArgumentException()
{
var languageToDelete = new Language("English");
var employee = new Mock<Employee>();
employee.Setup(x => x.Languages).Returns(new List<Languages>
{
new Language("Spanish"),
new Language("German")
});
employee.Object.DeleteLanguage(languageToDelete);
// Asserts here
}
[事实]
public void add language\u AfterCallWithValidObject\u language集合contained addedObject()
{
var language=newmock();
var employee=新员工(“姓名”、“姓氏”、…);
employee.AddLanguage(language.Object);
Assert.Contains(employee.EmployeeLanguages,x=>x.Language.Equals(Language.Object));
}
[事实]
public void delete language_当使用给定的语言时,不能使用文本列表_ThrowArgumentException()
{
var languageToDelete=新语言(“英语”);
var employee=new Mock();
employee.Setup(x=>x.Languages).Returns(新列表
{
新语言(“西班牙语”),
新语言(“德语”)
});
employee.Object.DeleteLanguage(languageToDelete);
//在这里断言
}
在第一次测试中,我还要断言调用了Languages.Add(skill)方法,但我不知道如何执行
对于行为非常简单且没有依赖关系的域对象,不严格需要模拟。您只需使用以下命令即可测试
添加:
//Arrange
var e = new Employee();
var l = new Mock<Language>();
//Act
e.AddLanguage(l.Object);
//Assert
Assert.IsTrue(e.Languages.Contains(l.Object));
//排列
var e=新员工();
var l=新的Mock();
//表演
e、 AddLanguage(l.Object);
//断言
IsTrue(e.Languages.Contains(l.Object));
通过这种方式进行测试,您可以获得非常好的代码覆盖率,并对Employee类按设计工作充满信心。对于行为非常简单且没有依赖关系的域对象,不需要严格模拟。您只需使用以下命令即可测试添加:
//Arrange
var e = new Employee();
var l = new Mock<Language>();
//Act
e.AddLanguage(l.Object);
//Assert
Assert.IsTrue(e.Languages.Contains(l.Object));
//排列
var e=新员工();
var l=新的Mock();
//表演
e、 AddLanguage(l.Object);
//断言
IsTrue(e.Languages.Contains(l.Object));
通过这种方式进行测试,您可以获得非常好的代码覆盖率,并对Employee类按设计工作充满信心。您应该将对象作为“黑盒”进行测试,而不依赖于实现细节。在您的例子中,实现细节是Employee
类使用ICollection.Add
方法
在你的情况下,你完全不需要嘲笑。
仅模拟依赖项,这将使测试速度变慢或测试配置非常复杂。
[Fact]
public void AddLanguage_ShouldSaveGivenLanguage()
{
var language = new Language();
var employee = new Employee("Name", "Surname");
employee.AddLanguage(language);
var expectedLanguages = new[] { language };
employee.EmployeeLanguages.Should().BeEquivalentTo(expectedLanguages);
}
使用公共APIEmployee
classprovide为测试(后台)设置它。
用于测试DeleteLanguage
通过类的公共API添加虚拟语言
[Fact]
public void DeleteLanguage_WhenLanguageExists_Remove()
{
var language1 = new Language("German");
var language2 = new Language("French");
var languageToDelete = new Language("English");
var employee = new Employee("Name", "Surname");
employee.AddLanguage(language1);
employee.AddLanguage(language2);
employee.AddLanguage(languageToDelete);
employee.DeleteLanguage(languageToDelete);
var expectedLanguages = new[] { language1, language2 };
employee.EmployeeLanguages.Should().BeEquivalentTo(expectedLanguages);
}
[Fact]
public void DeleteLanguage_WhenLanguageNotExists_ThrowException()
{
var language1 = new Language("German");
var language2 = new Language("French");
var notExistedLanguage = new Language("English");
var employee = new Employee("Name", "Surname");
employee.AddLanguage(language1);
employee.AddLanguage(language2);
Action delete = () => employee.DeleteLanguage(languageToDelete);
delete.Should()
.Throw<ArgumentException>()
.WithMessage("Language entry doesn't exist.");
}
[事实]
public void DeleteLanguage_当语言存在时_Remove()
{
var language1=新语言(“德语”);
var language2=新语言(“法语”);
var languageToDelete=新语言(“英语”);
var员工=新员工(“姓名”);
employee.AddLanguage(语言1);
employee.AddLanguage(语言2);
employee.AddLanguage(languageToDelete);
employee.DeleteLanguage(languageToDelete);
var expectedLanguages=new[]{language1,language2};
employee.EmployeeLanguages.Should().BeEquivalentTo(expectedLanguages);
}
[事实]
public void DeleteLanguage_,当Languagenote通过Exception()存在时
{
var language1=新语言(“德语”);
var language2=新语言(“法语”);
var notExistedLanguage=新语言(“英语”);
var员工=新员工(“姓名”);
employee.AddLanguage(语言1);
employee.AddLanguage(语言2);
Action delete=()=>employee.DeleteLanguage(languageToDelete);
删除.Should()
.Throw您应该将对象作为“黑盒”进行测试,而不依赖于实现细节。在您的示例中,实现细节是Employee
类使用ICollection.Add
方法
在你的情况下,你完全不需要嘲笑。
仅模拟依赖项,这将使测试速度变慢或测试配置非常复杂。
[Fact]
public void AddLanguage_ShouldSaveGivenLanguage()
{
var language = new Language();
var employee = new Employee("Name", "Surname");
employee.AddLanguage(language);
var expectedLanguages = new[] { language };
employee.EmployeeLanguages.Should().BeEquivalentTo(expectedLanguages);
}
使用公共APIEmployee
classprovide为测试(后台)设置它。
用于测试DeleteLanguage
通过类的公共API添加虚拟语言
[Fact]
public void DeleteLanguage_WhenLanguageExists_Remove()
{
var language1 = new Language("German");
var language2 = new Language("French");
var languageToDelete = new Language("English");
var employee = new Employee("Name", "Surname");
employee.AddLanguage(language1);
employee.AddLanguage(language2);
employee.AddLanguage(languageToDelete);
employee.DeleteLanguage(languageToDelete);
var expectedLanguages = new[] { language1, language2 };
employee.EmployeeLanguages.Should().BeEquivalentTo(expectedLanguages);
}
[Fact]
public void DeleteLanguage_WhenLanguageNotExists_ThrowException()
{
var language1 = new Language("German");
var language2 = new Language("French");
var notExistedLanguage = new Language("English");
var employee = new Employee("Name", "Surname");
employee.AddLanguage(language1);
employee.AddLanguage(language2);
Action delete = () => employee.DeleteLanguage(languageToDelete);
delete.Should()
.Throw<ArgumentException>()
.WithMessage("Language entry doesn't exist.");
}
[事实]
public void DeleteLanguage_当语言存在时_Remove()
{
var language1=新语言(“德语”);
var language2=新语言(“法语”);
var languageToDelete=新语言(“英语”);
var员工=新员工(“姓名”);
employee.AddLanguage(语言1);
employee.AddLanguage(语言2