如何为构建器设计模式编写单元测试



我正在使用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的详细信息,因此不确定如何覆盖containspersist步骤。

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 */ );

最新更新