在 VS 2013 的 C# 代码测试方法中有效使用 Shim
valid use of Shim in a Test Method in VS 2013 for c# code
我有以下测试方法代码:
[TestMethod]
public void TestWithNotNull()
{
using (ShimsContext.Create())
{
ShimMyConfiguration.Constructor = @this => new ShimMyConfiguration()
{
return;
};
ShimMyConfiguration.AllInstances.LoadValuesFromConfigXmlNode = (a,b) =>
{
return;
};
var _MyConfigurationHandler = new MyConfigurationHandler();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml("<Common.Mys><Mys><add name=\"LoggingErrorMessage\"/><remove name=\"LoggingMessageBox\"/></Mys></Common.Mys>");
var config = _MyConfigurationHandler.Create(null, null, xmlDoc.SelectSingleNode("Common.Mys"));
Assert.IsNotNull(config);
}
}
实际Code/Method我正在测试:
public object Create(object parent, object configContext, XmlNode section)
{
if (section == (XmlNode)null)
throw new ArgumentNullException("section");
MyConfiguration config = new MyConfiguration();
config.LoadValuesFromConfigXml(section);
return config;
}
我对上述创建方法进行单元测试的方式是否正确?因为我有以下问题:
我已经填充了构造函数,但没有做实际构造函数 MyConfiguration 会做的事情。是否必须执行实际构造函数所做的事情?如果是这样,我们如何在 ShimMyConfiguration 中实例化 MyConfiguration?
我填充了 LoadValuesFromConfigXmlNode,但不关心语句 config.LoadValuesFromConfigXml(section) 返回时包含的配置对象。
由于第 1 点和第 2 点,我只是在测试配置是否不为空。但是这样验证就足够了吗,还是我真的需要针对调用中传递的 xml 内容进行测试 _MyConfigurationHandler.Create(null, null, xmlDoc.SelectSingleNode("Common.Mys")) 返回的是什么?
任何答案都将帮助我评估我是否充分利用了垫片。
就目前而言,您的测试毫无意义。我可以用下面的代码满足测试:
public object Create(object parent, object configContext, XmlNode section)
{
return new int();
}
如果这是 Create
方法的众多测试之一,那么这不是世界末日,只要其他测试涵盖所需行为的其余部分即可。
根据您发布的方法,我想至少编写以下测试:
- 验证如果提供的部分为空,则抛出
ArgumentNullException
。
- 验证提供给您的
Create
调用的部分是否已传递给 MyConfiguration
的实例,并且同一实例是否从 Create
调用返回。
假设测试 1 存在于其他地方,测试 2 可能如下所示:
[TestMethod]
public void TestMyConfigurationUsedToReadConfiguration()
{
MyConfiguration calledOnInstance = null;
MyConfiguration returnedInstance = null;
XmlNode calledWithSection = null;
XmlNode sectionIn = null;
using (ShimsContext.Create())
{
ShimMyConfiguration.Constructor = @this => new ShimMyConfiguration()
{
return;
};
ShimMyConfiguration.AllInstances.LoadValuesFromConfigXmlNode = (a,b) =>
{
calledOnInstance = a;
calledWithSection = b;
return;
};
var _MyConfigurationHandler = new MyConfigurationHandler();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml("<Common.Mys><Mys><add name=\"LoggingErrorMessage\"/><remove name=\"LoggingMessageBox\"/></Mys></Common.Mys>");
sectionIn = xmlDoc.SelectSingleNode("Common.Mys");
returnedInstance = _MyConfigurationHandler.Create(null, null, sectionIn);
}
Assert.IsNotNull(returnedInstance);
Assert.AreEqual(returnedInstance, calledOnInstance);
Assert.AreEqual(sectionIn, calledWithSection);
}
我有以下测试方法代码:
[TestMethod]
public void TestWithNotNull()
{
using (ShimsContext.Create())
{
ShimMyConfiguration.Constructor = @this => new ShimMyConfiguration()
{
return;
};
ShimMyConfiguration.AllInstances.LoadValuesFromConfigXmlNode = (a,b) =>
{
return;
};
var _MyConfigurationHandler = new MyConfigurationHandler();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml("<Common.Mys><Mys><add name=\"LoggingErrorMessage\"/><remove name=\"LoggingMessageBox\"/></Mys></Common.Mys>");
var config = _MyConfigurationHandler.Create(null, null, xmlDoc.SelectSingleNode("Common.Mys"));
Assert.IsNotNull(config);
}
}
实际Code/Method我正在测试:
public object Create(object parent, object configContext, XmlNode section)
{
if (section == (XmlNode)null)
throw new ArgumentNullException("section");
MyConfiguration config = new MyConfiguration();
config.LoadValuesFromConfigXml(section);
return config;
}
我对上述创建方法进行单元测试的方式是否正确?因为我有以下问题:
我已经填充了构造函数,但没有做实际构造函数 MyConfiguration 会做的事情。是否必须执行实际构造函数所做的事情?如果是这样,我们如何在 ShimMyConfiguration 中实例化 MyConfiguration?
我填充了 LoadValuesFromConfigXmlNode,但不关心语句 config.LoadValuesFromConfigXml(section) 返回时包含的配置对象。
由于第 1 点和第 2 点,我只是在测试配置是否不为空。但是这样验证就足够了吗,还是我真的需要针对调用中传递的 xml 内容进行测试 _MyConfigurationHandler.Create(null, null, xmlDoc.SelectSingleNode("Common.Mys")) 返回的是什么?
任何答案都将帮助我评估我是否充分利用了垫片。
就目前而言,您的测试毫无意义。我可以用下面的代码满足测试:
public object Create(object parent, object configContext, XmlNode section)
{
return new int();
}
如果这是 Create
方法的众多测试之一,那么这不是世界末日,只要其他测试涵盖所需行为的其余部分即可。
根据您发布的方法,我想至少编写以下测试:
- 验证如果提供的部分为空,则抛出
ArgumentNullException
。 - 验证提供给您的
Create
调用的部分是否已传递给MyConfiguration
的实例,并且同一实例是否从Create
调用返回。
假设测试 1 存在于其他地方,测试 2 可能如下所示:
[TestMethod]
public void TestMyConfigurationUsedToReadConfiguration()
{
MyConfiguration calledOnInstance = null;
MyConfiguration returnedInstance = null;
XmlNode calledWithSection = null;
XmlNode sectionIn = null;
using (ShimsContext.Create())
{
ShimMyConfiguration.Constructor = @this => new ShimMyConfiguration()
{
return;
};
ShimMyConfiguration.AllInstances.LoadValuesFromConfigXmlNode = (a,b) =>
{
calledOnInstance = a;
calledWithSection = b;
return;
};
var _MyConfigurationHandler = new MyConfigurationHandler();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml("<Common.Mys><Mys><add name=\"LoggingErrorMessage\"/><remove name=\"LoggingMessageBox\"/></Mys></Common.Mys>");
sectionIn = xmlDoc.SelectSingleNode("Common.Mys");
returnedInstance = _MyConfigurationHandler.Create(null, null, sectionIn);
}
Assert.IsNotNull(returnedInstance);
Assert.AreEqual(returnedInstance, calledOnInstance);
Assert.AreEqual(sectionIn, calledWithSection);
}