我正在嘗試創建自己的 Mock 函式。我知道 Moq 存在,但我真的很想實作這一點。
我不知道如何創建一個 Mock 函式來存根 User#Foobar 對 Product#Price 的呼叫,以便對 User#Foobar 進行單元測驗:
using System;
public class MyUnitTest
{
// CODE BEING TESTED
class Product {
public string Price() {
return "I WANT TO STUB THIS OUT, DONT WANT TO SEE THIS STRING";
}
}
class User {
public string Foobar() {
Product product = new Product();
return $"Foobar, Product#price returns: {product.Price()}";
}
}
//////////////////////
// CODE THAT DOES THE TEST
public void Mock(string mockedClass, string mockedFunction, string mockedReturn)
{
// no idea what to put here something to do with an interface
}
public void RunTests()
{
Mock("Product","Price","MOCKED DATA");
string expected = new User().Foobar();
Assert(expected, "Foobar, Product#price returns: MOCKED DATA");
}
public void Assert(string actual, string expected){
Console.WriteLine(actual == expected);
}
//////////////////////
// How do I stub out Product to return "MOCKED DATA"?
}
public class Program
{
public static void Main(){
new MyUnitTest().RunTests();
}
}
我知道如何在 Ruby 中做到這一點,但在 C# 中卻不知道。
這是問題的 NET 小提琴:
https://dotnetfiddle.net/8Re2jb
這個 Mock 函式應該如何攔截 User#Foobar 對 Product#Price 的呼叫并回傳字串“MOCKED DATA”?
public void Mock(string mockedClass, string mockedFunction, string mockedReturn)
{
}
uj5u.com熱心網友回復:
您應該使用依賴注入來解決這個問題。物件User不應該知道. Product相反,您應該封裝Product在一個介面后面并將一個或某種工廠IProduct傳遞給User建構式。IProductIProduct
例如:
public interface IProduct
{
public string Price();
}
public interface IUser
{
public string FooBar();
}
public class User: IUser
{
public User(Func<IProduct> productFactory)
{
_productFactory = productFactory;
}
public string FooBar()
{
var product = _productFactory();
return $"Foobar, Product#price returns: {product.Price()}";
}
readonly Func<IProduct> _productFactory;
}
然后你可以創建你自己的“模擬”產品(我們應該稱之為存根):
public class MockProduct : IProduct
{
public MockProduct(string mockPrice)
{
_mockPrice = mockPrice;
}
public string Price()
{
return _mockPrice;
}
readonly string _mockPrice;
}
然后在您的測驗中,您可以創建User并傳遞給它一個工廠方法來創建一個模擬IProduct:
Func<IProduct> mockProductFactory = () => new MockProduct("MOCKED DATA");
User user = new User(mockProductFactory);
// Test user now.
盡管這實際上是一種存根(您已經使用過的術語)而不是模擬 - 模擬通常使用模擬框架完成并使用反射來避免必須手動實作介面中的所有方法。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/484652.html
