[英]How to manually stub out a function in C# unit testing
我正在尝试创建自己的 Mock function。我知道 Moq 存在,但我真的很想完成这个。
我不知道如何创建 Mock function 来阻止 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://do.netfiddle.net/8Re2jb
这个 Mock function 应该如何拦截 User#Foobar 对 Product#Price 的调用并返回字符串“MOCKED DATA”?
public void Mock(string mockedClass, string mockedFunction, string mockedReturn)
{
}
您应该使用依赖注入来解决这个问题。 User
object 不应该知道Product
的具体类型。 相反,您应该将Product
封装在一个IProduct
接口后面,并将一个IProduct
或某种IProduct
工厂传递给User
构造函数。
例如:
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.
虽然这实际上是一种存根形式(您已经使用过的术语)而不是 mocking - mocking 通常使用 mocking 框架完成,并使用反射来避免必须手动实现接口中的所有方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.