问题
I have this function in my interface and it creates a new PlayersBadge entry in the db. I have to write unit tests for and I'm stuck.
public void Badge(int pID, int bID, int gID = 0)
{
var list = EliminationDbContext.PlayerBadges.Where(x=>x.Badge.BadgeID.Equals(bID) && x.Player.PlayerID.Equals(pID));
//if player doesn't have Badge create new Badge
if (list.Any() != true)
{
PlayerBadge b = new PlayerBadge { PlayerID = pID, BadgeID = bID, DateEarned = DateTime.Today, GameID = gID };
EliminationDbContext.PlayerBadges.Add(b);
EliminationDbContext.SaveChanges();
}
}
回答1:
You have several options. One of them is giving the db communication responsibility to Repository classes and injecting these implementations in your business class. When writing unit tests, you can mock repositories and verify them.
Another option is to directly mocking DataContext as below :
private Mock<DataContext> _mockedContext;
private Mock<DbSet<MyEntity>> _mockedMyEntitiyDbSet;
And in your test case :
[Test]
public void CargoTicket_WithValidRequest_Verify_SaveChanges()
{
//assuming DbContext injected to your _sut object in setup
MockDbSet(myEntities);
_sutObject.Badge(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>()); // SaveChanges calling in here
_mockedContext.Verify(s => s.SaveChanges(), Times.Once);
}
You can mock DbSet as below :
private void MockDbSet(List<MyEntity> myEntities)
{
_mockedMyEntitiyDbSet= new Mock<DbSet<MyEntity>>().SetupData(myEntities);
_mockedContext.Setup(s => s.MyEntities).Returns(_mockedMyEntitiyDbSet.Object);
}
来源:https://stackoverflow.com/questions/49983787/how-do-i-unit-test-a-void-function-that-inserts-into-the-database-and-saves