Should this case of Assert.AreSame return true?

2019-07-04 06:27发布

I am testing a repository pattern I have created and I use Moq package to mock my objects. I wanted to test references from 2 objects, but the result kind of surprises me. Here is the test:

Mock<Repository<Web_Documents>> moqRepo;
Mock<Repository<Web_Documents>> moqRepo2;

public void ObjEqGetTest()
{
    //context is DBContext and has been initialized using [TestInitialize] annotation
    moqRepo = new Mock<Repository<Web_Documents>>(context);
    moqRepo2 = new Mock<Repository<Web_Documents>>(context);
    var test = moqRepo.Object.Get(1L);
    var test2 = moqRepo2.Object.Get(1L);
    Assert.AreSame(test, test2);
}

And my Get method returns:

return entities.SingleOrDefault(predicate)

predicate being created using Expression builder (I can add code if needed).

Why does this Assert return true, when I have created two differents objects?

Is it that the Get method returns the same reference whenever you fetch data from a DB (since it points to the model being used)?

Thanks for your help!

EDIT @CodeCaster said Mocking repos will return null in the request I made. But When I verify values in my table Web_Documents, Assertions return true. Let me demonstrate this :

public void IdExistsGetTest()
{
    moqDoc = new Mock<Repository<Web_Documents>>(context);
    var testDoc = moqDoc.Object.Get(1L);
    Assert.AreEqual(testDoc.NomDocument, "Ajouter une catégorie");
}

This test is successful, and in Web_Documents, the row at ID = 1 has NomDocument = "Ajouter une catégorie".

2条回答
Explosion°爆炸
2楼-- · 2019-07-04 07:09

I assume context is Entity Framework context. You share it between your two repositories, so your two queries on different repositories will return the same entity, because Entity Framework "caches" entities (in certain sense) inside the context. When it sees your query returns entity which is already attached to the context (in this case - returned by first query) - it will return the same entity again for the second one (entities are "same" if they have the same primary key and type).

查看更多
闹够了就滚
3楼-- · 2019-07-04 07:09

Evk already answered why the return values are identical: the DbContext returns the same instance for the same primary key.

I wanted to say something about your code though. Here:

moqRepo = new Mock<Repository<Web_Documents>>(context);
moqRepo2 = new Mock<Repository<Web_Documents>>(context);

You're mocking the class you want to test. You shouldn't mock the class under test, you should mock its dependencies.

So mock the DbContext, and inject that into your non-mocked repos:

var contextMock = new Mock<DbContext>(MockBehavior.Strict);

var repo = new Repository<Web_Documents>(MockBehavior.Strict, contextMock.Object);
var repo2 = new Repository<Web_Documents>(MockBehavior.Strict, contextMock.Object);

Now you'll have to set up the contextMock to return what you want. when called the way it's called by your Get() methods.

See for example Mocking EF DbContext with Moq for more mocking of Entity Framework.

查看更多
登录 后发表回答