I know there are a lot of these kind of questions/articles and I've read a lot of them multiple times, but I'm still stuck.
I have a very simple code. Database=>Entity Framwork=>Repository=>Logic=>Display and now tests. My problem that I couldn't find any help how to test my CRUD operations. I only have the following instructions: "Test with mocked repository". So the following is out of question.
[Test]
public void TestThatReadCrewWorks()
{
CrewLogic logic = new CrewLogic();
var result = logic.LReadCrew(102);
Assert.That(result.Name, Is.EqualTo("Test Joe"));
}
How can I use my repository (which uses dbcontext) to test independently, without giving test dll the connectionstring? I tried...
[Test]
public void TestThatCreatingCrewWorks2()
{
DbContext ctx;
CrewRepository newc = new CrewRepository(ctx);
}
...and from here complete darkness. What should dbcontext be here?
Any help, even link is highly appropriated. Thank you.
edit: clarification
public abstract class Repository<T> : IRepository<T>
where T : class
{
protected DbContext ctx;
public Repository(DbContext ctx)
{
this.ctx = ctx;
}
public T Read(int id)
{
return this.ctx.Set<T>().Find(id);
}
//...and other crud operations
}
I have this syntax. How do I write test which depends on this general DBcontext rather than my actual database. Should I create fake class somehow?
Your repository is simply wrapping DbContext
. DbContext
on its own has already been tested by Microsoft before being released. No need to test that a DbContext
does what it was designed to do.
To test that the repository used the context as expected then you need to do an integration test with an actual context. Either mock the DbContext
or use an in-memory DbContext
. Either way, your tests will be giving a false sense of security since you are basically testing wrapped code that has already been tested by its developer.
For example your return this.ctx.Set<T>().Find(id);
in the base repository. Everything in that line is DbContext
related and not worth you testing that is does what it is suppose to do.
For example, look at the following test of that same repository method
[Test]
public void CrewWorks_Should_Find_By_Id() {
//Arrange
int expectedId = 102;
string expectedName = "Test Joe";
Crew expected = new Crew {
Id = expectedId,
Name = "Test Joe"
};
Mock<DbContext> ctxMock = new Mock<DbContext>();
ctxMock
.Setup(_ => _.Set<Crew>().Find(expcetedId))
.Returns(expected);
DbContext ctx = ctxMock.Object;
CrewRepository subject = new CrewRepository(ctx);
//Act
Crew actual = subject.Read(expectedId);
//Assert
Assert.That(actual, Is.EqualTo(expected));
}
The above test verifies expected behavior for the wrapped DbContext
related calls and does not really provide much in terms of security since it basically is testing that wrapped code is invoked.
Ideally the repository should be mocked and used to test the logic at higher levels
[Test]
public void TestThatReadCrewWorks() {
int expectedId = 102;
string expectedName = "Test Joe";
Crew expected = new Crew {
Id = expectedId,
Name = "Test Joe"
};
//Assuming abstraction of specific repository
// interface ICrewPrepsitory: IRepository<Crew> { }
ICrewPrepsitory repository = Mock.Of<ICrewPrepsitory>(_ =>
_.Read(expectedId) == expected
);
CrewLogic logic = new CrewLogic(repository); //assuming injection
//Act
var actual = logic.LReadCrew(expectedId);
//Assert
Assert.That(actual.Name, Is.EqualTo(expectedName));
//...other assertions
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.