"I've used a separate db to check this in unit testing. But many
experienced people said if I use this method that won't be unit
testing; that's integration testing."
Those people are mistaken, despite their supposed experience. For some reason, the incorrect notion that unit tests are all about testing parts of your code in isolation has grown in popularity in recent years. In reality, unit testing is all about writing tests that act as a unit, in other words they exist in isolation and the result of one unit test cannot influence another test.
If your UpdateUser
method directly accesses EF, then as long as you ensure the database is guaranteed to be rolled back to its starting state at the end of each test, then you have unit tests. However, setting the database up for each test and ensuring it can be reliably rolled back can be a lot of work. That is why mocks are often used. Other answers have covered mcoking EF, so I won't go over that.
To greatly simplify your tests, you could have an extrapolation layer between UpdateUser
and EF. In other words, the UpdateUser
class is supplied with an instance of an interface, which is its gateway into EF. It doesn't talk to EF directly. To then mock EF, you simply supply a mocked implementation of the interface. This then pushes the need to test against EF down into a more basic layer, with more basic CRUD-like behaviours.