I am using xunit for my unit testing and I am new to unit testing. I have a builder class like below,
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;
}
I would like to unit test the Build()
, Validate()
and SetName()
but I don't have DB details with me and hence, not sure how to override contains
and persist
steps.
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);
}
}
Moreover, how can I check if the name is lower case after calling SetName() from the private _user field?
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);
}
}
CodePudding user response:
I've used the Moq library for this. https://github.com/moq/moq4
Usage would look something like this:
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);
Update for the additional question about validation of SetName() method:
Since the only method exposed to get the User
is the Build()
method you would need to leverage that and then verify that the name is what you expect. Something like this:
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 */ );