当前位置: 首页 > 知识库问答 >
问题:

如何对使用相同私有方法的公共方法进行单元测试?

章睿
2023-03-14

我需要一些软件测试方面的指导。

我把事情复杂化了,但我太专注了,看不到我做错了什么,也看不到其他做事方式。

我有几个公共方法使用相同的私有方法。

私有方法本身:

  • 必须为其特定角色处理许多场景

假设私有方法需要5个测试来覆盖所有场景,并由6个公共方法使用。

问题

>

  • 然后我是否需要至少5x6个测试?

    如何对每个公共方法重复使用私有方法的测试?

    有没有关于重构重复测试的示例/文章?

    示例

    OnStartup()

    - if_file_exists_load_entries           ()
    - if_file_missing_load_last             ()
    - if_no_files_create_new_entries        ()
    - if_exception_clear_entries_and_log    ()
    - loaded_entries_init_called            ()
    - Other tests
    

    OnUserLoadCustom()

    - if_file_exists_load_entries           _AND_STORE_AS_LAST()
    - if_file_missing_load_last             _AND_STORE_AS_LAST_AND_WARNING_MESSAGE()
    - if_no_files_create_new_entries        _AND_WARNING_MESSAGE()
    - if_exception_clear_entries_and_log    _AND_ERROR_MESSAGE()
    - loaded_entries_init_called            _AND_SUCCESS_MESSAGE()
    - Other tests
    

    在线恢复()

    - if_file_exists_load_entries           _AND_INFO_MESSAGE()
    - if_file_missing_load_last             _AND_INFO_MESSAGE()
    - if_no_files_create_new_entries        _AND_INFO_MESSAGE()
    - if_exception_clear_entries_and_log    _AND_ERROR_MESSAGE_AND_SHUTDOWN()
    - loaded_entries_init_called            _AND_SUCCESS_MESSAGE()
    - Other tests
    

    我正在考虑使用策略模式封装私有方法,这样我就可以单独测试它(和公共方法)。

    然而,我觉得使用它不合适,因为:

    • 我不打算在运行时有可互换的行为
    • 为了更容易的测试而使用模式似乎是错误的

    更新#1

    我的问题与测试私有方法行为的公共接口有关。但是我最终得到了许多重复的测试方法(参见上面的示例)。

    对于战略模式,我认为我需要的是:

    • 测试策略中的所有路径(基本上,测试私有方法)

    但是就像我提到的,我不认为我应该仅仅为了更容易的测试而引入一个模式。除非真的有必要,否则我将推迟这种方法。

    减少重复的第一次尝试:

    >

  • 私有方法测试分组到自己的类中(行为1测试)

    • GetTestCases()返回与此行为相关的测试用例列表

    所有需要此测试的公共方法都实现了公开

    • Arrange()
    • Act()
    • 断言()

    例如:

    // Public method tests
    [TestFixture]
    public class PublicMethodTests: IBehaviour1Test
    {
        // Behaviour 1
        Behaviour1Test _behaviour1;
        IEnumerable<TestCaseData> Behaviour1TestCases{ get { return _behaviour1.GetTestCases(); } }
        [Test]
        [TestCaseSource("Behaviour1TestCases")]
        public void RunBehaviour1Test(Action<IBehaviour1Test> runTestCase)
        {
            runTestCase(this);
        }
    
        // ==============================
        // Behaviour 1 Arrange/act/assert
        void IBehaviour1Test.Arrange(){}
        void IBehaviour1Test.Assert(object result){}
        object IBehaviour1Test.Act()
        {
            return _model.PublicMethod();        
        }
    
        // Other tests
    }
    
    // Implement this in order to run Behaviour1 test cases
    interface IBehaviour1Test
    {
        void Arrange(); 
        object Act();
        void Assert(object retValue);
    }
    
    // Collection of tests for behaviour 1
    public class Behaviour1Test
    {
        // Generate test cases
        IEnumerable<TestCaseData>() GetTestCases()
        {
            yield return new TestCaseData((Action<IBehaviour1Test>)Test_1);
            yield return new TestCaseData((Action<IBehaviour1Test>)Test_2);
            yield return new TestCaseData((Action<IBehaviour1Test>)Test_3);
        }
    
        void Test_1(IBehaviour1Test impl)
        {
            // Arrange
            impl.Arrange(); // public method's arrange
            Test1Setup(); // Arrange for this test
    
            // Act
            var result = impl.Act();
    
            // Assert
            Test1Assert(result); // Assert for this test
            impl.Assert(result); // Assert on public method
    
        }
    
        void Test_2(IBehaviour1Test impl){}
        void Test_3(IBehaviour1Test impl){}
    }
    

    这样,如果我需要为私有方法的行为添加一个新的测试用例,我只需要在行为测试中添加一次,所有包含它的公共方法测试都将被更新。

  • 共有3个答案

    澹台浩广
    2023-03-14

    您需要将私有方法提取到助手类中。然后分别测试其功能,并在其他测试中模拟它。私有方法中的功能与您试图在其他方法中测试的内容无关——它只提供输入。大多数私有方法通常只是等待释放的助手方法。

    闻人梓
    2023-03-14

    在某种意义上,你不需要测试私有方法。您彻底地测试了使用私有方法的方法,所有这些都证明了私有方法“有效”。

    如果您真的想安心,可以使用反射来执行私有方法,这样您就可以单独测试它。

    关于测试重构,您当然应该有设置和拆卸例程来处理这些各自的函数。我不会在测试中讨论策略模式,只需在测试类中创建非测试方法,这些方法具有多个测试所需的功能块,并适当使用它们。例如,如果您的私有方法可以影响5个字段,并且您需要多次测试这5个字段,那么我将创建一个如下的方法

    private void verifyField(expected1, extpected2, ....){
         equals(actual1, expected1, 'expected1 correct);
         ....
    }
    

    并在适当的时候使用它。

    邢小云
    2023-03-14

    您应该在测试中应用与在应用程序代码中相同的原理。如果可以将公共功能提取到助手方法或类中,那么您应该这样做。它将节省代码重复,并在私有方法更改时帮助您稍后重构。

    我想您有很多可以通用的常见设置、拆解、断言和验证代码。

     类似资料:
    • 我有一个类,它有一个公共方法,它调用另一个私有方法。 通过调用公共方法 并将 设置为 来进行测试。 将更改为package-private并在测试中直接调用它。 然而,我不确定哪种方法更好。

    • 以下是设置: 我需要测试公共方法,以检查是否筛选了invalidObjects。如您所见,它将传递给私有的方法。该方法过滤掉无效的对象,并将有效的对象发送给web服务方法。该web服务方法不返回任何内容。因此,我不知道是否只有有效的对象被发送到web服务方法。你建议我怎么做才能检验这个案子?我正在使用Mockito框架来模拟对象。

    • 在我们的ASP。Net核心应用程序,我们有许多API从服务类调用公共方法。 服务类正在实现一个接口。 每个服务方法(取决于复杂性和需求)可以调用任意数量的内部或私有或辅助方法。 虽然这些内部/私有/或辅助方法中的每一个都单独进行单元测试,但我们如何以这样一种方式测试公共服务方法,即我们不必重复已经在测试内部/私有/辅助方法中花费的代码/精力? e、 我们可以很容易地模拟接口方法,说接口方法需要这些

    • 我是单元测试的新手,最近尝试了JUnit测试和Mockito。 我很困惑我该如何测试公共功能。

    • 我陷入了单元测试场景的一个基本问题,并将感谢帮助。 我有一个类,它调用在DB中将标志设置为true。 我的测试: 我被要求测试并检查是否正在使用相关数据调用。 由于返回类型无效,我如何测试它?

    • 问题内容: 我当时正在上课,我想到了几个问题。 我注意到,其他类将使用的公共方法调用了一些私有方法来完成所有工作。现在,我知道OOD的原则之一就是尽可能多地私有化并隐藏所有实现细节。我不确定我是否完全理解其背后的逻辑。 我知道将字段设为私有很重要,以防止将无效值存储在字段中(这只是许多原因之一)。但是,对于私有方法,我不确定为什么它们如此重要。 例如,对于类,我们是否不能将所有实现代码都放入公共方