how can I use NSubstitute for stub and mock? any difference about the usage?
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.
作者:Chuck Lu GitHub |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
2022-03-22 炉石传说 佣兵战纪 限时任务
2022-03-22 炉石传说 佣兵战纪 奥妮克希亚的巢穴
2021-03-22 Vulnerability Assessment And Penetration Testing
2019-03-22 我如何向 HR MM 介绍 Microservice
2019-03-22 sql server查看用户权限
2018-03-22 Recommended Settings for Tracing and Message Logging
2018-03-22 Union