我应该将一个私有方法变为公共方法,只是为了测试吗?

huangapple go评论67阅读模式
英文:

Should I make a private method public just for testing?

问题

以下是您要翻译的代码部分:

I have a C# service with two methods:

private IEnumerable<RowsBalance> GetUpdatedRowsBalance(IEnumerbale<OrderRows> rows)
{
    //Do something important I want to test
}

public void UpdateBalance(int orderId)
{
    //Gets order rows from database
    var rows = orderRepository.GetRows(orderId);

    //Get updated balance
    var updatedBalanceRows = GetUpdatedRowsBalance(rows);

    //Save updated balance to database
    orderRepository.SaveBalance(updatedBalanceRows);
}

有关代码可测试性的考虑,请查看以下翻译:

"私有方法包含我需要测试的逻辑,我应该考虑什么以使我的代码可测试?

我考虑以下几点:

  1. GetUpdatedRowsBalance 方法变为公共方法并进行测试。是否可以将某些永远不会在测试之外被调用的内容设为公共?
  2. 将需要测试的重要业务逻辑分离到不同的类中。这仍然可行,但不会在其他地方重复使用。
  3. 使公共方法返回可进行断言的内容,如 updatedBalanceRows。我不太喜欢只为测试而返回不需要的内容。

我不太确定如何处理这种情况。"

英文:

I have a C# service with two methods:

private IEnumerable<RowsBalance> GetUpdatedRowsBalance(IEnumerbale<OrderRows> rows)
{
    //Do something important I want to test
}

public void UpdateBalance(int orderId)
{
    //Gets order rows from database
    var rows = orderRepository.GetRows(orderId);

    //Get updated balance
    var updatedBalanceRows = GetUpdatedRowsBalance(rows);

    //Save updated balance to database
    orderRepository.SaveBalance(updatedBalanceRows);
}

The private method has the logic I need to test, what should I consider in order to make my code testable ?

I'm thinking about:

  • Make GetUpdatedRowsBalance public and test that. Is it ok to make something public that will never be called outside of testing ?
  • Separate the important business logic I need to test on a different class. Still ok but this is not going to be reused elsewhere.
  • Make the public method returns something I can assert like updatedBalanceRows. I don't really like returns something I don't need just for testing.

I'm note sure how to approach this scenario.

答案1

得分: 4

你可以按原样进行测试。

只需创建自己版本的orderRepository

以下是一个非常简单的API示例,可以根据您的喜好进行修改(或者如果您倾向于这种方式,可以使用Moq)。

// 测试

// 准备
var orderRepositoryDouble = new OrderRepositoryDouble();
orderRepositoryDouble.Rows = someFakeRows;
var sut = new Whatever(orderRepositoryDouble);

// 执行
sut.UpdateBalance();

// 断言
var updatedRows = orderRepositoryDouble.UpdatedRows;

// 随便怎样。

// 测试替身
class OrderRepositoryDouble : IRepo
{
    public IEnumerable<OrderRows> Rows { get; set; }
    public IEnumerable<OrderRows> GetRows(int orderId) => Rows;

    public IEnumerable<RowsBalance> UpdatedRows { get; set; }

    public void SaveBalance(IEnumerable<RowsBalance> r) =>
        UpdatedRows = r;
}
英文:

You could test it as it is.

Just create your own version of orderRepository.

Here's an example of a very crude API, alter to your preference (or use Moq if you are that way inclined).

// The Test

// Arrange
var orderRepositoryDouble = new OrderRepositoryDouble();
orderRepositoryDouble.Rows = someFakeRows;
var sut = new Whatever(orderRepositoryDouble);

// Act
sut.UpdateBalance();

// Assert
var updatedRows = orderRepositoryDouble.UpdatedRows;

// Whatever.

// The test double
class OrderRepositoryDouble : IRepo
{
    public IEnumerable&lt;OrderRows&gt; Rows { get; set; }
    public GetRows(int orderId) =&gt; Rows;

    public IEnumerable&lt;RowsBalance&gt; UpdatedRows { get; set; }

    public void SaveBalance(IEnumerable&lt;RowsBalance&gt; r) =&gt;
        UpdatedRows = r;
}

huangapple
  • 本文由 发表于 2023年3月7日 23:48:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/75664204.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定