I am testing a private method using JustMock and that works fine. However, to verify the method worked correctly, I need to pull the value of a public property that the private method loads. Basically, the constructor loads a set of configuration XML documents and exposes them through a public property of a configuration class.
So I am able to mock the private method that is executed from the contrstructor (InitializeFile) and it works fine. But I want to create a couple of asserts to verify the public property has the values that it should and that it is not empty. But since I have mocked a private method, I don't have a way to get to the public property. At least I do not see how to do that and none of the examples I have come across this show this.
Here's the test I have come up with so far. The GetProperty() fails becuase the property is a public property and I have mocked up a PrivateAccessor. So what do you have to do to mock a priviate method, but also have access to get the value of a public property... or can you with JusMock?
So I am able to mock the private method that is executed from the contrstructor (InitializeFile) and it works fine. But I want to create a couple of asserts to verify the public property has the values that it should and that it is not empty. But since I have mocked a private method, I don't have a way to get to the public property. At least I do not see how to do that and none of the examples I have come across this show this.
Here's the test I have come up with so far. The GetProperty() fails becuase the property is a public property and I have mocked up a PrivateAccessor. So what do you have to do to mock a priviate method, but also have access to get the value of a public property... or can you with JusMock?
public
void
LoadConfiguartionSettingsTest()
{
// Arrange
var inst = PrivateAccessor.ForType(
typeof
(Configuration));
var xdoc = (XDocument)inst.CallMethod(
"InitializeFile"
);
// Act
inst.CallMethod(
"LoadConfiguartionSettings"
,
new
object
[] { xdoc });
var resp = inst.GetProperty(
"AppSettings"
); // This fails... I guess because it is a public property.
// Assert
Assert.IsNotNull(resp);
Assert.IsInstanceOfType(resp,
typeof
(List<AppSetting>));
}
5 Answers, 1 is accepted
0
Hi Greg,
Thank you for contacting us.
You should be able to call public members with the JustMock's Private Accessor. I executed your test with the following system under test:
and it passed.
However, as it is possible to call public members via the Private Accessor in most of the cases this is not needed. For example, I wrote the same test method like this:
and it passed again.
Please, let me know if your system under test is somehow different and this does not work. In such case, I will be happy to assist you further on the matter.
Regards,
Kaloyan
Telerik
Thank you for contacting us.
You should be able to call public members with the JustMock's Private Accessor. I executed your test with the following system under test:
public
class
AppSetting
{
}
public
class
XDocument
{
}
public
static
class
Configuration
{
private
static
void
LoadConfiguartionSettings()
{
AppSettings =
new
List<AppSetting>();
}
private
static
XDocument InitializeFile()
{
return
new
XDocument();
}
public
static
List<AppSetting> AppSettings {
get
;
set
; }
}
However, as it is possible to call public members via the Private Accessor in most of the cases this is not needed. For example, I wrote the same test method like this:
[TestMethod]
public
void
LoadConfiguartionSettingsTest()
{
// Arrange
var inst = PrivateAccessor.ForType(
typeof
(Configuration));
var xdoc = (XDocument)inst.CallMethod(
"InitializeFile"
);
// Act
inst.CallMethod(
"LoadConfiguartionSettings"
);
var resp = Configuration.AppSettings;
// Assert
Assert.IsNotNull(resp);
Assert.IsInstanceOfType(resp,
typeof
(List<AppSetting>));
}
Please, let me know if your system under test is somehow different and this does not work. In such case, I will be happy to assist you further on the matter.
Regards,
Kaloyan
Telerik
0
Greg
Top achievements
Rank 1
answered on 24 Oct 2013, 02:52 PM
Thanks for your feedback and sample code. Seeing that it works for you helped me to identify my issue. It looks like the issue is just that my property is actually not a property... but just a public field. I flipped it to a property and it works fine. Also, I did not have the static accessor in the class name, as in C# it is not required if all of the methods and properties are static, the class is static. However, I can see that JustMock cannot see that. So I set to static and not use the default accessor so JustMock would see it.
But I am still having issues. So I adjusted this to show you what is going on. I adjusted the code to load a small configuration XML string and use that in the LoadConfigurationSettings method call. With my fake config file I only have 3 appSettings. The real one has 79 appSettings. So now when the LoadConfigurationSettings method is called, I pass in the fake 3 appSetting config XML document. However, it still loads the 79 from the real file. I think that means that when I call LoadConfiguraitonSettings(), as new instance of the configuration class is created, the non-faked version of the configuration is loaded, and that is what is returned to be verified in my unit test. However, the point of the unit test is to not depend on the real config.xml file. So the fake one is what I need to work. However, I cannot figure out what JustMock is doing here and how to correct it. I have tried working through a number of difference ways to mock this based on the online samples. But this is the only one that seems to work for a static class. But I still cannot resolve the last issue, which is to use my fake XML document. It always loas the real one.
Any ideas what JustMock is doing here? I do not understand what is going on and how to get it to work correctly.
Here's the GetConfigFile() that just loads a fake XML document with only 3 appSettings.
Here's the actual configuraiton class with comments and extra fluff removed.
But I am still having issues. So I adjusted this to show you what is going on. I adjusted the code to load a small configuration XML string and use that in the LoadConfigurationSettings method call. With my fake config file I only have 3 appSettings. The real one has 79 appSettings. So now when the LoadConfigurationSettings method is called, I pass in the fake 3 appSetting config XML document. However, it still loads the 79 from the real file. I think that means that when I call LoadConfiguraitonSettings(), as new instance of the configuration class is created, the non-faked version of the configuration is loaded, and that is what is returned to be verified in my unit test. However, the point of the unit test is to not depend on the real config.xml file. So the fake one is what I need to work. However, I cannot figure out what JustMock is doing here and how to correct it. I have tried working through a number of difference ways to mock this based on the online samples. But this is the only one that seems to work for a static class. But I still cannot resolve the last issue, which is to use my fake XML document. It always loas the real one.
Any ideas what JustMock is doing here? I do not understand what is going on and how to get it to work correctly.
public
void
LoadConfiguartionSettingsTest()
{
// Arrange
var inst = PrivateAccessor.ForType(
typeof
(Configuration));
// Act
inst.CallMethod(
"LoadConfiguartionSettings"
,
new
object
[] { GetConfigFile() });
var resp = inst.GetProperty(
"AppSettings"
);
// Assert
Assert.IsNotNull(resp);
Assert.IsInstanceOfType(resp,
typeof
(List<AppSetting>));
}
private
XDocument GetConfigFile()
{
string
xmlString =
"<?xml version=\"1.0\" encoding=\"utf-8\"?><configuration><appSettings key=\"GSA_Comments\" value=\"Additional Comments\" /><appSettings key=\"GSA_Address1\" value=\"Address 1\" /></configuration>"
;
return
XDocument.Parse(xmlString);
}
Here's the actual configuraiton class with comments and extra fluff removed.
public
class
Configuration
{
public
static
List<AppSetting> AppSettings {
get
;
set
; }
public
static
string
AppPath {
get
;
set
; }
static
Configuration()
{
AppSettings =
new
List<AppSetting>();
XDocument xdoc = InitializeFile();
LoadConfiguartionSettings(xdoc);
}
private
static
XDocument InitializeFile()
{
var configFile =
""
;
AppPath = HostingEnvironment.ApplicationPhysicalPath;
if
(
string
.IsNullOrEmpty(AppPath)) // local debugging
AppPath = @
"C:\Projects\Source\Data\"
;
try
{
configFile = Path.Combine(AppPath,
"config.xml"
);
return
XDocument.Load(configFile);
}
catch
(System.Exception ex)
{
throw
new IOException(string.Format("Could load config.xml into XML document. Path: {0} Error: {1}", AppPath, ex.Message));
}
}
private
static
void
LoadConfiguartionSettings(XDocument xdoc)
{
var query = (from attrib
in
xdoc.Descendants(
"configuration"
).Descendants(
"appSettings"
)
select
new
AppSetting
{
Key = attrib.Attribute(
"key"
).Value,
Value = attrib.Attribute(
"value"
).Value
}).ToList();
foreach
(var item
in
query)
{
AppSetting ap =
new
AppSetting();
ap.Key = item.Key;
ap.Value = item.Value;
AppSettings.Add(ap);
}
}
public
static
string
GetAppSetting(
string
strKey)
{
var ret = (from item
in
AppSettings
where item.Key == strKey
select item.Value).FirstOrDefault();
return
ret;
}
}
0
Hi Greg,
Thank you for the detailed information provided. It really helps to investigate the matter faster :).
I was able to reproduce the issue. Debugging the test method, I noticed that the static constructor of the Configuration class was invoked. As it is calling the InitializeFile() and the LoadConfigurationSettings() methods, with a default values (in your case the real config.xml file), it was causing the issue.
To prevent this, I added a SetupStatic function which mocks the static constructor and in the same time sets CallOriginal behavior. More about this can be found here. Further, I also needed an initialization of the AppSettings property (to prevent a NullReferenceException at the end of the LoadConfigurationSettings method). The final test looks like this:
It passes. Also, after getting the AppSettings property, you can see that the resp.Count is actually 2.
I hope this helps and works as expected on your side. Let me know if I can be of a further assistance.
Regards,
Kaloyan
Telerik
Thank you for the detailed information provided. It really helps to investigate the matter faster :).
I was able to reproduce the issue. Debugging the test method, I noticed that the static constructor of the Configuration class was invoked. As it is calling the InitializeFile() and the LoadConfigurationSettings() methods, with a default values (in your case the real config.xml file), it was causing the issue.
To prevent this, I added a SetupStatic function which mocks the static constructor and in the same time sets CallOriginal behavior. More about this can be found here. Further, I also needed an initialization of the AppSettings property (to prevent a NullReferenceException at the end of the LoadConfigurationSettings method). The final test looks like this:
[TestMethod]
public
void
LoadConfiguartionSettingsTest()
{
// Arrange
Mock.SetupStatic(
typeof
(Configuration), Behavior.CallOriginal, StaticConstructor.Mocked);
Configuration.AppSettings =
new
List<AppSetting>();
var inst = PrivateAccessor.ForType(
typeof
(Configuration));
// Act
inst.CallMethod(
"LoadConfiguartionSettings"
,
new
object
[] { GetConfigFile() });
var resp = inst.GetProperty(
"AppSettings"
);
// Assert
Assert.IsNotNull(resp);
Assert.IsInstanceOfType(resp,
typeof
(List<AppSetting>));
}
I hope this helps and works as expected on your side. Let me know if I can be of a further assistance.
Regards,
Kaloyan
Telerik
0
Greg
Top achievements
Rank 1
answered on 25 Oct 2013, 01:34 PM
Works perfectly! That makes complete sense and works exactly as it I need to. Thanks for taking the time to resolve this for me.
I'll read through the static mocking link that you provided, as most of my problems is just not being familiar with JustMock and how things are done. Step by step I am catching on. Thanks for pointing me in the right direction here.
Best regards,
Jon
I'll read through the static mocking link that you provided, as most of my problems is just not being familiar with JustMock and how things are done. Step by step I am catching on. Thanks for pointing me in the right direction here.
Best regards,
Jon
0
Hi Greg,
Great to hear that!
I believe the best source to get familiar with JustMock is our online help documentation. There are articles for all the JustMock features and functionalities. Another good source are the shipped with JustMock example solutions. You can find the in the JustMock install folder, under Examples\. Note, there C# and VB.NET examples there.
Also, I will be happy to assist you if you have more questions or issues. So, do not hesitate to contact our support services.
Have a nice day and happy mocking :).
Regards,
Kaloyan
Telerik
Great to hear that!
I believe the best source to get familiar with JustMock is our online help documentation. There are articles for all the JustMock features and functionalities. Another good source are the shipped with JustMock example solutions. You can find the in the JustMock install folder, under Examples\. Note, there C# and VB.NET examples there.
Also, I will be happy to assist you if you have more questions or issues. So, do not hesitate to contact our support services.
Have a nice day and happy mocking :).
Regards,
Kaloyan
Telerik