Ninject 传递给单元测试的 DI 参数
Ninject DI arguments passing to the unit test
这是我的构造函数,具有 ILogger 依赖性
public Book(string isbn, string author, string title, string publisher, int publishYear, ushort pageNumber, decimal price, ILogger logger)
{
Isbn = isbn;
Author = author;
Title = title;
Publisher = publisher;
PublishYear = publishYear;
PageNumber = pageNumber;
Price = price;
_logger = logger;
_logger.Log(LogLevel.Info, "Book constructor has been invoked");
}
我的单元测试尝试通过 Ninject 框架解决它
[TestCase("9783161484100", "Some Name", "C# in a nutshell", "Orelly", 2014, (ushort)900, 60, ExpectedResult = "Some Name Orelly")]
[Test]
public string FormatBook_FortmattingBooksObject_IsCorrectString(string isbn, string author, string title, string publisher, int year, ushort pages, decimal price)
{
using (IKernel kernel = new StandardKernel())
{
var book = kernel.Get<Book>();
Console.WriteLine(book.FormatBook(book.Author, book.Publisher));
return book.FormatBook(book.Author, book.Publisher);
}
}
问题是,如何注入依赖项并将参数传递给构造函数?
不需要在单元测试中注入东西。只需为记录器使用模拟对象:
[TestCase("9783161484100", "Some Name", "C# in a nutshell", "Orelly", 2014, (ushort)900, 60, ExpectedResult = "Some Name Orelly")]
[Test]
public string FormatBook_FortmattingBooksObject_IsCorrectString(string isbn, string author, string title, string publisher, int year, ushort pages, decimal price)
{
ILogger fakeLogger = ...; //Create some mock logger for consumption
var book = new Book(isbn, author, title, publisher, year, pages, price, fakeLogger);
Console.WriteLine(book.FormatBook(book.Author, book.Publisher));
return book.FormatBook(book.Author, book.Publisher);
}
这并不是说内核也不能提供记录器,如果您愿意的话,但是您必须先设置它然后再获取它:
[TestCase("9783161484100", "Some Name", "C# in a nutshell", "Orelly", 2014, (ushort)900, 60, ExpectedResult = "Some Name Orelly")]
[Test]
public string FormatBook_FortmattingBooksObject_IsCorrectString(string isbn, string author, string title, string publisher, int year, ushort pages, decimal price)
{
INinjectModule module = ...;//Create a module and add the ILogger here
using (IKernel kernel = new StandardKernel(module))
{
var fakeLogger = kernel.Get<ILogger>(); //Get the logger
var book = new Book(isbn, author, title, publisher, year, pages, price, fakeLogger);
Console.WriteLine(book.FormatBook(book.Author, book.Publisher));
return book.FormatBook(book.Author, book.Publisher);
}
}
如前所述,在单元测试中您通常不需要使用容器。但关于更一般的问题:
How to pass my arguments to the constructor?
您可以这样做:
kernel.Get<Book>(
new ConstructorArgument("isbn", "123"),
new ConstructorArgument("author", "XYZ")
...
);
这是我的构造函数,具有 ILogger 依赖性
public Book(string isbn, string author, string title, string publisher, int publishYear, ushort pageNumber, decimal price, ILogger logger)
{
Isbn = isbn;
Author = author;
Title = title;
Publisher = publisher;
PublishYear = publishYear;
PageNumber = pageNumber;
Price = price;
_logger = logger;
_logger.Log(LogLevel.Info, "Book constructor has been invoked");
}
我的单元测试尝试通过 Ninject 框架解决它
[TestCase("9783161484100", "Some Name", "C# in a nutshell", "Orelly", 2014, (ushort)900, 60, ExpectedResult = "Some Name Orelly")]
[Test]
public string FormatBook_FortmattingBooksObject_IsCorrectString(string isbn, string author, string title, string publisher, int year, ushort pages, decimal price)
{
using (IKernel kernel = new StandardKernel())
{
var book = kernel.Get<Book>();
Console.WriteLine(book.FormatBook(book.Author, book.Publisher));
return book.FormatBook(book.Author, book.Publisher);
}
}
问题是,如何注入依赖项并将参数传递给构造函数?
不需要在单元测试中注入东西。只需为记录器使用模拟对象:
[TestCase("9783161484100", "Some Name", "C# in a nutshell", "Orelly", 2014, (ushort)900, 60, ExpectedResult = "Some Name Orelly")]
[Test]
public string FormatBook_FortmattingBooksObject_IsCorrectString(string isbn, string author, string title, string publisher, int year, ushort pages, decimal price)
{
ILogger fakeLogger = ...; //Create some mock logger for consumption
var book = new Book(isbn, author, title, publisher, year, pages, price, fakeLogger);
Console.WriteLine(book.FormatBook(book.Author, book.Publisher));
return book.FormatBook(book.Author, book.Publisher);
}
这并不是说内核也不能提供记录器,如果您愿意的话,但是您必须先设置它然后再获取它:
[TestCase("9783161484100", "Some Name", "C# in a nutshell", "Orelly", 2014, (ushort)900, 60, ExpectedResult = "Some Name Orelly")]
[Test]
public string FormatBook_FortmattingBooksObject_IsCorrectString(string isbn, string author, string title, string publisher, int year, ushort pages, decimal price)
{
INinjectModule module = ...;//Create a module and add the ILogger here
using (IKernel kernel = new StandardKernel(module))
{
var fakeLogger = kernel.Get<ILogger>(); //Get the logger
var book = new Book(isbn, author, title, publisher, year, pages, price, fakeLogger);
Console.WriteLine(book.FormatBook(book.Author, book.Publisher));
return book.FormatBook(book.Author, book.Publisher);
}
}
如前所述,在单元测试中您通常不需要使用容器。但关于更一般的问题:
How to pass my arguments to the constructor?
您可以这样做:
kernel.Get<Book>(
new ConstructorArgument("isbn", "123"),
new ConstructorArgument("author", "XYZ")
...
);