我正在使用xunit进行单元测试,我是单元测试的新手。我有一个像下面这样的建设者类,
public class UserBuilder
{
private User _user = new User();
public UserBuilder UserBuilder(IDataBase db) //IDatabase is available in a different Nuget package which I don't have source code access
{
this._user.db = db;
}
public UserBuilder SetName(string name)
{
this._user.name = name.ToLower();
}
public UserBuilder SetRole(string role)
{
this._user.role = role.ToUpper();
}
public void Validate()
{
if (this._user.name == null)
throw new InvalidDataException();
if (this._user.db.contains(this._user.name)
throw new InvalidDataException();
......
}
public User Build()
{
this.validate();
this._user.db.persist();
return this._user;
}
我想对Build()
、Validate()
和SetName()
进行单元测试,但我没有DB的详细信息,因此不确定如何覆盖contains
和persist
步骤。
public class UserBuilderTest
{
[Fact]
public void Task_SetName_John()
{
// Arrange
// How to Mock the IDatabase?
var builder = new UserBuilder(FakeDatabase);
// Act
var actual = builder.Validate();
// Assert
Assert.Throws<InvalidDataException>(action);
}
}
此外,从private_user字段调用SetName((后,如何检查名称是否为小写?
public class UserBuilderTest
{
[Fact]
public void Task_SetName_John()
{
// Arrange
// How to Mock the IDatabase?
var builder = new UserBuilder(FakeDatabase);
var expected = 'john";
// Act
var actual = builder.SetName("John");
// Assert
Assert.Equals(expected, actual);
}
}
我已经为此使用了Moq库。https://github.com/moq/moq4
用法如下:
var mockDatabase = new Mock<IDataBase>();
// Do setups on the mock if necessary
// mockDatabase.Setup( m => m.SomeMethodOnTheInterface() ).Returns( new Something() );
var builder = new UserBuilder(mockDatabase.Object);
关于SetName((方法验证的附加问题的更新:
由于获得User
的唯一方法是Build()
方法,因此您需要利用它,然后验证名称是否符合您的期望。类似这样的东西:
var mockDatabase = new Mock<IDataBase>();
var builder = new UserBuilder(mockDatabase.Object);
var user = builder.SetName("John Doe").Build();
Assert.AreEqual("john doe", user.Name /* assuming this is a property */ );