C
C#3d ago
surwren

✅ Mocking DB operations

Say I have a function and I need to verify that the saved UserFollow object will: 1. Cause the user objects to be retrieved if UserFollow retrieves them eagerly 2. Cause the userFollow to be retrieved if a User is retrieved with said fields eagerly public async Task<bool> AddFollowerByPrivateIdAsync(int userPrivateId, int followerPrivateId) { var user = await _context.Users.FirstOrDefaultAsync(u => u.PrivateId == userPrivateId);
var follower = await _context.Users.FirstOrDefaultAsync(u => u.PrivateId == followerPrivateId);
if (user == null || follower == null) {
return false;
}
var userFollow = new UserFollow {
FollowedId = [user.Id]
FollowerId = [follower.Id] Type = FollowType.Requested,
Followed = user,
Follower = follower
};
_context.UserFollows.Add(userFollow);
await _context.SaveChangesAsync();
return true; } How would I test this? I have looked at XUnit and MockItEasy but it doesn't look like they are dealing with the Database, but rather dependencies for abstracted code.
44 Replies
Thalnos
Thalnos3d ago
You should really create an abstraction for anything and everything if you want to mock it easily for testing. That’s one of the reasons why wrapping EFC into your own repository pattern even tho it already is an implementation of it is beneficial
surwren
surwrenOP3d ago
I don't really understand I mock it (in all the examples I've seen) I'm just feeding it the behavior to output? How do I test the actual DB behavior itself
Unknown User
Unknown User3d ago
Message Not Public
Sign In & Join Server To View
MODiX
MODiX3d ago
see $mockef
Unknown User
Unknown User3d ago
Message Not Public
Sign In & Join Server To View
MODiX
MODiX3d ago
GitHub
GitHub - romantitov/MockQueryable: Mocking Entity Framework Core op...
Mocking Entity Framework Core operations such ToListAsync, FirstOrDefaultAsync etc - romantitov/MockQueryable
Unknown User
Unknown User3d ago
Message Not Public
Sign In & Join Server To View
surwren
surwrenOP3d ago
wait, why would mockef not be reliable if it is recommended by modix too 😳
Unknown User
Unknown User3d ago
Message Not Public
Sign In & Join Server To View
surwren
surwrenOP3d ago
MSSQL
Unknown User
Unknown User3d ago
Message Not Public
Sign In & Join Server To View
surwren
surwrenOP3d ago
I actually don't know that there are options for where tests can be ran, I came from Java where I would create a folder called 'tests' and it would just not let the build pass if tests failed (when I pressed the play button)
Unknown User
Unknown User3d ago
Message Not Public
Sign In & Join Server To View
surwren
surwrenOP3d ago
sure, I do believe integration tests are close to what I am looking for anyway
Unknown User
Unknown User3d ago
Message Not Public
Sign In & Join Server To View
surwren
surwrenOP3d ago
if we start at most basic it's just locally/only me for now but I'm curious how it could be done with local + ci/cd with all the team too, since I would want to learn how to do that at some point
Unknown User
Unknown User3d ago
Message Not Public
Sign In & Join Server To View
surwren
surwrenOP3d ago
I am already using docker with docker-compose.yml
services:
service-social:
...

mssql:
image: mcr.microsoft.com/mssql/server:2022-latest
environment:
SA_PASSWORD: "..."
ACCEPT_EULA: "Y"
ports:
- "1433:1433"
volumes:
- mssql-data:/var/opt/mssql

volumes:
mssql-data:
services:
service-social:
...

mssql:
image: mcr.microsoft.com/mssql/server:2022-latest
environment:
SA_PASSWORD: "..."
ACCEPT_EULA: "Y"
ports:
- "1433:1433"
volumes:
- mssql-data:/var/opt/mssql

volumes:
mssql-data:
Unknown User
Unknown User3d ago
Message Not Public
Sign In & Join Server To View
surwren
surwrenOP3d ago
Say I just want to unit test on my own for now which is the bare minimum I need? to get some integration tests working like the simplest of integration tests, maybe just do a simple eager loading from EFCore and verify if the object was eagerly loaded should I just go for this? would this be the option to spin an empty Database/testcontainer
Unknown User
Unknown User3d ago
Message Not Public
Sign In & Join Server To View
surwren
surwrenOP3d ago
oh, there is a sample testing package using SUTs thank you, I will take a look would this still entail the TestContainer? If not, when would that be applicable?
Thalnos
Thalnos3d ago
@TeBeCo Im curious tho, wouldn’t an integration test using a local or dev db negate the purpose of the integration test? From my understanding it should use the actual prod DB, am I wrong? Not a copy but the real one, as if you use a copy it would be a unit test, not an integration test, right?
Unknown User
Unknown User3d ago
Message Not Public
Sign In & Join Server To View
Thalnos
Thalnos3d ago
Sure, awaiting your reply later pls 🙂
Unknown User
Unknown User3d ago
Message Not Public
Sign In & Join Server To View
Thalnos
Thalnos3d ago
Yes that’s the main point I thought of. If you only copy the data from the prod db to dev db once a day which is how it was done in my teams, that it’s possible the data is inconsistent. But besides data inconsistency there could also be network related differences How would the copy of the data usually be done? I imagine once a day how we did it is not great if you suggest to use a clone db for this
Unknown User
Unknown User3d ago
Message Not Public
Sign In & Join Server To View
Thalnos
Thalnos3d ago
So you‘d include a job to reconstruct dev DB into the CI/CD pipeline that executes the integration test then?
Unknown User
Unknown User3d ago
Message Not Public
Sign In & Join Server To View
Thalnos
Thalnos3d ago
How bout network differences tho? The dev db is surely not hosted on same machine as the prod db is it?
Unknown User
Unknown User3d ago
Message Not Public
Sign In & Join Server To View
Thalnos
Thalnos3d ago
Yes but what I mean is you could think your db works fine because the tests against your dev db pass, while the prod db is actually not even accessible cuz of some network related issues Oh I guess that would be noticed cuz the job of creating the dev db would fail, nvm Thank you
Unknown User
Unknown User3d ago
Message Not Public
Sign In & Join Server To View
surwren
surwrenOP2d ago
I am having some trouble setting up the SQL connection with my Dockerfile
Service_Social_Tests.ControllerTests.WhenCallingController_ShouldReturnOK
 Source: ControllerTests.cs line 7
 Duration: 15.1 sec

Message: 
Microsoft.Data.SqlClient.SqlException : A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)
---- System.ComponentModel.Win32Exception : The network path was not found.
Service_Social_Tests.ControllerTests.WhenCallingController_ShouldReturnOK
 Source: ControllerTests.cs line 7
 Duration: 15.1 sec

Message: 
Microsoft.Data.SqlClient.SqlException : A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)
---- System.ComponentModel.Win32Exception : The network path was not found.
I am told that this is one solution (manually start the docker compose within each test):
var startInfo = new System.Diagnostics.ProcessStartInfo {
FileName = "docker-compose",
Arguments = "-f docker-compose.test.yml up -d",
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
var process = System.Diagnostics.Process.Start(startInfo);
process.WaitForExit();
await Task.Delay(30000);
var startInfo = new System.Diagnostics.ProcessStartInfo {
FileName = "docker-compose",
Arguments = "-f docker-compose.test.yml up -d",
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
var process = System.Diagnostics.Process.Start(startInfo);
process.WaitForExit();
await Task.Delay(30000);
But this does not look very modular? What is the popular/accepted way to do this?
Unknown User
Unknown User2d ago
Message Not Public
Sign In & Join Server To View
surwren
surwrenOP2d ago
no, it's WebApplicationFactory I'll check testcontainer, I thought they were two differen things- I guess I should be using WebApplicationFactory and testcontainer together?
Unknown User
Unknown User2d ago
Message Not Public
Sign In & Join Server To View
surwren
surwrenOP2d ago
Unknown User
Unknown User2d ago
Message Not Public
Sign In & Join Server To View
surwren
surwrenOP2d ago
Do you know of sample projects that integrate both? Just so I can reference in case I get stuck ok nvm I found some in their git repo
surwren
surwrenOP2d ago
GitHub
testcontainers-dotnet/examples/WeatherForecast at develop · testcon...
A library to support tests with throwaway instances of Docker containers for all compatible .NET Standard versions. - testcontainers/testcontainers-dotnet
surwren
surwrenOP2d ago
thanks
Unknown User
Unknown User2d ago
Message Not Public
Sign In & Join Server To View

Did you find this page helpful?