gpt4 book ai didi

c# - 在没有实例的情况下将 FakeItEasy A.CallTo 与 Instance MethodInfo 一起使用

转载 作者:行者123 更新时间:2023-11-30 16:58:38 24 4
gpt4 key购买 nike

我正在尝试测试一种方法,该方法具有创建 IDisposable 类型的新具体实例的 using 语句。

为此,我试图伪造一个在 IDisposable 类型的构造函数中执行的私有(private)方法。我可以更改代码,使其更易于测试,但我想先知道这种方式是否可行。

到目前为止我有:

  1. 使用反射获取指向私有(private)方法的MethodInfo对象
  2. 根据 MethodInfo 对象创建一个 Expression 类型
  3. 如果执行该表达式,则告诉 FakeItEasy 不执行任何操作

说明我的问题的示例代码

namespace FakeUsing
{
using System;
using System.Linq.Expressions;
using System.Runtime.Remoting.Messaging;

using FakeItEasy;

using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Reflection;

// Application under test
class Program
{
public bool success = false;

// Entry Point
static void Main(string[] args)
{
Program p = new Program();
p.Run();
}

// Method I would like to test
public void Run()
{
using (new Concrete("data"))
{
// Code I actually want to test.
success = true;
}
}
}

// Problem class that I cannot change
public class Concrete : IDisposable
{
public Concrete(string data)
{
PrivateCall();
}

private void PrivateCall()
{
// Some stuff that uses unmanaged resources
// I'm not interested in testing
DoStuff();
}

public void Dispose()
{
// Some stuff that uses unmanaged resources
// I'm not interested in testing
DoStuff();
}

private void DoStuff()
{
throw new NotImplementedException();
}
}

// Testing code
[TestClass]
public class UnitTests
{
[TestMethod]
public void TestRun()
{
// Arrange
Program p = new Program();
MethodInfo doStuffMethodInfo =
typeof(FakeUsing.Concrete)
.GetMethod("DoStuff", BindingFlags.Instance | BindingFlags.NonPublic);

// This is the line I cannot get to work.
MethodCallExpression doStuffMCE =
Expression.Call(???, doStuffMethodInfo, null);
A.CallTo(doStuffMCE).DoesNothing();

// Act
p.Run();

// Assert
Assert.IsTrue(p.success);
}
}
}

在 FakeUsing.UnitTests.TestRun 中,我无法绕过创建 MethodCallExpression 实例,因为我手边没有实例。

谢谢

大卫

最佳答案

这是不可能的。 FakeItEasy 将只能拦截它创建的伪造方法,并且您新建生产类以进行测试。

即使有可能,我也不建议这样做。模拟 private 方法通常会导致(充其量)过度指定、脆弱的测试。一旦实现发生变化,所有测试都会中断。如果(正如您暗示的那样)您无法控制具有私有(private)方法的类,这尤其危险。

我认为更好的方法是更改​​生产代码(您可以更改)以使用某种工厂返回 IDisposable。然后提供返回一个什么都不做的对象的工厂实现。使用 FakeItEasy 这应该非常简单。 (甚至没有它!行为非常简单,如果您还没有模拟框架,则不需要模拟框架。)

关于c# - 在没有实例的情况下将 FakeItEasy A.CallTo 与 Instance MethodInfo 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25013048/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com