how can I use NSubstitute for stub and mock? any difference about the usage?
NSubstitute is a popular mocking library for .NET that allows you to create test doubles (stubs, mocks, etc.) for your dependencies in unit tests. The main difference between stubs and mocks is their purpose and how they are used in tests.
Stubs are used to provide predefined responses to method calls or property getters. They are typically used when you want to isolate the system under test (SUT) from its dependencies and control their behavior.
Mocks are used to verify that certain interactions occurred between the SUT and its dependencies. They are typically used when you want to ensure that the SUT is calling the correct methods or properties on its dependencies with the expected arguments.
Here's an example of how to use NSubstitute for creating a stub and a mock:
First, install the NSubstitute NuGet package:
Create an interface for the dependency you want to stub or mock:
public interface ICalculator
{
int Add(int a, int b);
int Multiply(int a, int b);
}
Use NSubstitute to create a stub:
using NSubstitute;
// ...
[Test]
public void TestAdditionWithStub()
{
// Arrange
var calculator = Substitute.For<ICalculator>();
calculator.Add(1, 2).Returns(3);
// Act
int result = calculator.Add(1, 2);
// Assert
Assert.AreEqual(3, result);
}
Use NSubstitute to create a mock:
using NSubstitute;
// ...
[Test]
public void TestAdditionWithMock()
{
// Arrange
var calculator = Substitute.For<ICalculator>();
// Act
calculator.Add(1, 2);
// Assert
calculator.Received().Add(1, 2);
}
In the first example, we create a stub for the ICalculator interface and configure it to return 3 when the Add method is called with arguments 1 and 2.
In the second example, we create a mock for the ICalculator interface and use the Received() method to verify that the Add method was called with the expected arguments.
In summary, you can use NSubstitute to create both stubs and mocks depending on your testing needs.
Stubs are used to provide predefined responses to method calls or property getters, while mocks are used to verify that certain interactions occurred between the system under test (SUT) and its dependencies.
Here's another example to demonstrate the difference between stubs and mocks using NSubstitute:
Suppose you have a UserService class that depends on an IUserRepository interface for fetching user data:
public interface IUserRepository
{
User GetUserById(int id);
void SaveUser(User user);
}
public class UserService
{
private readonly IUserRepository _userRepository;
public UserService(IUserRepository userRepository)
{
_userRepository = userRepository;
}
public string GetUserName(int id)
{
var user = _userRepository.GetUserById(id);
return user?.Name;
}
public void UpdateUserName(int id, string newName)
{
var user = _userRepository.GetUserById(id);
if (user != null)
{
user.Name = newName;
_userRepository.SaveUser(user);
}
}
}
Now, let's write tests for the GetUserName and UpdateUserName methods using stubs and mocks:
Create a stub for the IUserRepository interface to test the GetUserName method:
using NSubstitute;
using NUnit.Framework;
// ...
[Test]
public void TestGetUserNameWithStub()
{
// Arrange
var userRepository = Substitute.For<IUserRepository>();
userRepository.GetUserById(1).Returns(new User { Id = 1, Name = "Alice" });
var userService = new UserService(userRepository);
// Act
string userName = userService.GetUserName(1);
// Assert
Assert.AreEqual("Alice", userName);
}
In this test, we create a stub for the IUserRepository interface and configure it to return a User object with the name "Alice" when the GetUserById method is called with the argument 1.
Create a mock for the IUserRepository interface to test the UpdateUserName method:
using NSubstitute;
using NUnit.Framework;
// ...
[Test]
public void TestUpdateUserNameWithMock()
{
// Arrange
var userRepository = Substitute.For<IUserRepository>();
userRepository.GetUserById(1).Returns(new User { Id = 1, Name = "Alice" });
var userService = new UserService(userRepository);
// Act
userService.UpdateUserName(1, "Bob");
// Assert
userRepository.Received().GetUserById(1);
userRepository.Received().SaveUser(Arg.Is<User>(user => user.Id == 1 && user.Name == "Bob"));
}
In these tests, we create stubs and mocks for the IUserRepository interface to test the GetUserName and UpdateUserName methods of the UserService class.
标签:use,userRepository,int,NSubstitute,stub,user,interface,public From: https://www.cnblogs.com/chucklu/p/17243374.html