
I'm new to mocking and am playing with JustMock to mock Entity Framework 4. Therefore, my understanding of what I want to happen may be a reflection of my lack of understanding of mocking principles/implementation.
I have browsed around and found some resources, but they're not all that clear. Have seen:
- http://www.telerik.com/help/justmock/basic-usage-entity-framework-mocking.html (note that the cropping of code is less than useful, has to expose the source and find the "missing" text in the code snippet)
- ms-help://TelerikJustMock/TelerikJustMock/html/01863dc3-bc4b-4b97-8e3a-ea444c23d994.htm
So far, I have:
var entitiesMock = Mock.Create<Entities>();
This still wants the ConnectionString to appear in the app.config file of the Test DLL, which I would hope wouldn't be required? Without it, the default constructor throws an exception. Question 1: So am I right in thinking any unit tests I mock in this way are dependant on the DB - sort of making it a bit pointless?
My next task is to create an object and add it to the mocked entities:
UserAccount userAccount =
new
UserAccount()
{
Username =
"UserName"
,
Password =
"Password"
};
// Arrange
List<UserAccount> userAccounts =
new
List<UserAccount>();
Mock.Arrange(() => entitiesMock.AddToUserAccounts(Arg.IsAny<UserAccount>())).DoInstead(()=>userAccounts.Add(userAccount));
// Act
entitiesMock.AddToUserAccounts(userAccount);
// Assert
Assert.AreEqual(1, userAccounts.Count);
Assert.AreSame(userAccount, userAccounts[0]);
I understand this, and my object does indeed appear in the userAccounts collection. Win.
So in my head, I have an entity framework entities collection that I have mocked and primed with a user account. I would like to pass that into another class:
Authentication authentication =
new
Authentication(entitiesMock);
UserAccount authenticatedUserAccount=authentication.Authenticate(userAccount.Username, userAccount.Password, Authentication.PasswordFormat.PlainText);
Assert.AreEqual(userAccount.Username, authenticatedUserAccount.Username);
This uses the EF Model to return the user and authenticate their details.
This leaves the Question 2: when this code runs, the UserAccounts collection within the mocked Entities object is (understandably) null. Where am I going wrong? Am I wrong to expect to be able to prime the mocked entities with a single object and be able to use that?
Any help appreciated, I've made time in my project to work on Mocking and I need to get to grips with this fast!
Nathan
11 Answers, 1 is accepted
Thanks for bringing up the questions.
On your first issue, if target type is not sealed then JusMock tries to create the mock and implement its members (virtual) using proxy thus it does not need a profiler to intercept the ones which can be intercepted via simple inheritance.Therefore, it fires the default constructor which on the other hand requires a connection string in your config file for entity framework mocking (This behavior is similar to Moq)
But in certain cases, it is not expected / possible. Therefore, we recently added a way to specify that you want the constructor to be mocked as well. You will be able to do this through an additional parameter in Mock.Create<T>:
var entities = Mock.Create<Entities>(Constructor.Mocked);
This will be available in the coming Q1 release.
Next, for your second issue i am attaching a test project that shows an example to supply the mocked entity in a nested class and assert it accordingly.
In that particular example I have created the .edmx from NorthWind database and written the test in the following way:
var entities = Mock.Create<NorthwindEntities>();
Category category =
new
Category()
{
CategoryName =
"Beer"
};
// Arrange
List<Category> categories =
new
List<Category>();
Mock.Arrange(() => entities.AddToCategories(Arg.IsAny<Category>())).DoInstead(() => categories.Add(category));
Inventory inventory =
new
Inventory(entities);
inventory.PlaceOrder(category);
// Assert
Assert.AreEqual(1, categories.Count);
Assert.AreSame(category, categories[0]);
Finally, sorry for the documentation issue of "Cropping code"; we will fix that as soon as possible and please do feel free to write us back for any further issues.
Kind regards,
Ricky
the Telerik team

There is a way to mock the enumerable part of ObjectContext in a way to provide fake data?
Regards,
Nic
Thank you for the question.
Yes, it is possible to return fake data. To assist you further, please check the following example:
[TestMethod]
public
void
ShouldFakeDBCollectionReturn()
{
// Creating fake collection that should be returned in the fake DB
List<Category> fakeCategories =
new
List<Category>();
fakeCategories.Add(
new
Category { CategoryID = 32 });
fakeCategories.Add(
new
Category { CategoryName =
"Telerik"
});
// Arrange
var entities = Mock.Create<NorthwindEntities>();
Mock.Arrange(() => entities.Categories).ReturnsCollection(fakeCategories);
// Act
var actualCategories = entities.Categories;
// Assert
Assert.AreEqual(2, actualCategories.Count());
}
I have also attached the example project with the included new test method in it. I hope it works for you.
Please give us a note either if you require further assistance about this matter or anything else concerning JustMock.
All the best,
Kaloyan
the Telerik team

Thanks you Kaloyan
I am happy, I could help you.
Please contact us again, if you need anything else.
Greetings,
Kaloyan
the Telerik team

[TestMethod]
public void GetMockUnknownUserByName(){
//Arrangevar User = Mock.Create<CtrUser>();
Mock.Arrange(()=>User.Login).Returns("GLOBAL\\unknown"); //ensure User.Login returns Global\unknown
//Act
var mocked = User.Login;
//Assert
Assert.AreEqual("GLOBAL\\unknown", mocked);
}This test passes when run on it's own but when run with other tests it fails with:
Failed GetMockUnknownUserByName Riana.Tests Assert.AreEqual failed. Expected:<GLOBAL\unknown>. Actual:<>.
I believe it may have something to do with the way the CtrUser Class is constructed. (although why the outcome depends on how many test are run bothers me)
I'm using it in a factory pattern and it's constructor is private
public static CtrUser NewUser()
{
return DataPortal.Create<CtrUser>();
}
private CtrUser()
{ /* require use of factory method */ }
i have also tried :
var User = Mock.Create(()=>CtrUser.NewUser());
but this fails with:
System.NullReferenceException: Object reference not set to an instance of an object.
I know the solution is probably very simple, but how can I mock a property of a class constructed from a static factory method?
Thank you for reaching back to us.
The cause of this matter, could be that the CtrUser class has been already JIT compiled when the test is intercepting the mock. That is why this test will pass when run on its own and may fail along with other tests.
To avoid this, I would suggest to initialize the "CtrUser" class in the [ClassInitialize] or in the constructor of your test class. Below, you will find an example:
[TestClass]
public
class
JustMockTest
{
public
JustMockTest()
{
Mock.Initialize<CtrUser>();
}
[TestMethod]
public
void
GetMockUnknownUserByName()
{
//Arrange
var User = Mock.Create<CtrUser>();
Mock.Arrange(() => User.Login).Returns(
"GLOBAL\\unknown"
);
//ensure User.Login returns Global\unknown
//Act
var mocked = User.Login;
//Assert
Assert.AreEqual(
"GLOBAL\\unknown"
, mocked);
}
I hope this helps.
Regards,
Kaloyan
the Telerik team

I'm on a project that has multiple hands, and a remote dev database. We use an abstract base class for data access with the following:
public
abstract
class
DataAccessBase
{
Entities data;
protected
Entities ProjectEntities
{
get
{
return
data; }
set
{ data = value; }
}
public
DataAccessBase()
{
data =
new
Entities();
}
public
DataAccessBase(
string
connString)
{
data =
new
Entities(connString);
}
}
This way, from the test we can call:
OwnerData data =
new
OwnerData(ConfigurationManager.ConnectionStrings[
"USTEntities"
].ConnectionString);
and then after the object is populated:
List<QAQC> history =
new
List<QAQC>();
Mock.Arrange(() => data.SaveAuditTrail(Arg.IsAny<QAQC>())).DoInstead(()=> history.Add(histObj));
data.SaveAuditTrail(histObj);
Assert.AreEqual(1, history.Count());
Assert.AreEqual(pk, history[0].PrimaryKey);

That was it, am getting consistant results now.
Best regards,
Ray
I am glad the issue is solved now.
Do not hesitate to contact us again, if you need further assistance.
All the best,
Kaloyan
the Telerik team