Wil*_*ler 5 c# unit-testing ninject moq
使用Moq进行单元测试时,出现以下错误:
Message: System.NotSupportedException :
Invalid setup on non-virtual (overridable in VB) member:
cm => cm.AppSettings[It.IsAny<string>()]
Run Code Online (Sandbox Code Playgroud)
根据这些发现,我理解最好使用Moq的抽象类或接口.
简而言之,我完成了我的作业.=)
但是,如果我实际使用的是接口呢?
ConfigurationServiceTests
[TestFixture]
public class ConfigurationServiceTests {
[Test]
public void DialectShouldQueryConfigurationManagerAppSettings() {
// Given
configurationManagerMock
.Setup(cm => cm.AppSettings[It.IsAny<string>()])
.Returns(It.IsAny<string>());
// When
var dialect = configurationService.Dialect;
// Then
dialect.Should().BeOfType<string>();
configurationManagerMock.Verify(cm => cm.AppSettings[It.IsAny<string>()]);
}
[SetUp]
public void ConfigurationServiceSetUp() {
configurationManagerMock = new Mock<IConfigurationManager>();
configurationService =
new ConfigurationService(configurationManagerMock.Object);
}
private Mock<IConfigurationManager> configurationManagerMock;
private IConfigurationService configurationService;
}
Run Code Online (Sandbox Code Playgroud)
IConfigurationManager
public interface IConfigurationManager {
NameValueCollection AppSettings { get; }
ConnectionStringSettingsCollection ConnectionStrings { get; }
}
Run Code Online (Sandbox Code Playgroud)
IConfigurationService
public interface IConfigurationService {
string ConnectionDriver { get; }
string ConnectiongString { get; }
string Dialect { get; }
}
Run Code Online (Sandbox Code Playgroud)
ConfigurationService
public class ConfigurationService : IConfigurationService {
public ConfigurationService(IConfigurationManager configurationManager) {
this.configurationManager = configurationManager;
}
public string ConnectionDriver {
get { return configurationManager.AppSettings["ConnectionDriver"]; }
}
public string ConnectionString {
get {
return configurationManager
.ConnectionStrings[ConnectionStringKey]
.ConnectionString;
}
}
public string Dialect {
get { return configurationManager.AppSettings[DialectKey]; }
}
private readonly IConfigurationManager configurationManager;
private const string ConnectionStringKey = "DefaultConnectionString";
private const string DialectKey = "Dialect";
}
Run Code Online (Sandbox Code Playgroud)
为什么我创建了IConfigurationManager界面?
除此之外,我想在我的生产代码中使用Ninject直接绑定它.所以我不需要具体的接口实现,因此我对上述异常感到非常惊讶.
kernel.Bind<IConfiguration>().To<ConfigurationManager>().InSingletonScope();
Run Code Online (Sandbox Code Playgroud)
这样做可以让我对我进行单元测试ConfigurationService.
任何的想法?
你试图模拟索引器NameValueCollection而不是你的属性getter.
你需要做一些事情(注意SetupGet而不是Setup):
.SetupGet(cm => cm.AppSettings).Returns(....)
Run Code Online (Sandbox Code Playgroud)
如果你想要"mocked"集合返回"任何东西",你可能需要覆盖实际的类(检查是否有可能).
如果您知道要查找的设置 - 从Mock返回填充的集合可能是一个选项:
configurationManagerMock
.SetupGet(cm => cm.AppSettings)
.Returns(new NameValueCollection { {"SettingName", "Value"}});
Run Code Online (Sandbox Code Playgroud)
另一个选择是返回一些自定义界面,或者IDictionary<string,string>你也可以模拟索引:
interface IConfigurationManager
{
IDictionary<string,string> AppSettings { get; }
...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9434 次 |
| 最近记录: |