使用受保护的方法和模拟字段的单位测试C#

发布于 2025-02-13 01:13:07 字数 1579 浏览 0 评论 0原文

以下是我们主要项目使用的Nuget软件包中的代码,MyClass通过带有身份验证的主项目调用。方法GetMyAppStoreConfig()只有在通过身份验证从主项目拨打的时才能起作用。

  public class MyClass : MyClassBase
    {
        private SomeClass1 someClass1;
        private MyAppStore myAppStore; // Field newly added
        
        public MyClass(params object[] args)
            : base(args)
        {
            this.someClass1 = new SomeClass1();
            this.myAppStore = new MyAppStore(GetMyAppStoreConfig()); // Field newly added
        }

           protected override async Task<SomeValues> Process(
            SomeClass2 someClass2,
            SomeClass3 someClass3,
            SomeClass4 someClass4
           )
        {
          ...
          ...
          ...
  
        }
     
    // Below method uses myAppStore
    // Method newly added
        protected override async Task<SomeValues> ProcessWithAuth(
            SomeClass5 someClass5
           )
        {
          ...
          ...
          ...
  
        }

        private AppStoreConfig GetMyAppStoreConfig(){
        ...
        ...
        }


    }

以前的测试代码是上述。

 [TestClass()]
    public class MyClassTests : MyClass 
    {
        

        [TestMethod()]
        public void test1()
        {   
            ...
            ... = this.Process(someClass2,someClass3,someClass4);
            ...
        }
   }

但是现在它不起作用,因为它会在getMyAppStoreConfig()中引发错误。目前,我不需要测试ProcessWithAuth(),我应该为测试案例起作用的更改。

我目前无法创建一个又一个构造函数,也无法更改myClass.cs中的保护级别。

Process()有一些我想在测试中运行的代码,而不仅仅是模拟。

Below is code from a NuGet package which is used by our main project, MyClass is called via the main project with authentication. The method GetMyAppStoreConfig() will only work when calling from the main project via authentication.

  public class MyClass : MyClassBase
    {
        private SomeClass1 someClass1;
        private MyAppStore myAppStore; // Field newly added
        
        public MyClass(params object[] args)
            : base(args)
        {
            this.someClass1 = new SomeClass1();
            this.myAppStore = new MyAppStore(GetMyAppStoreConfig()); // Field newly added
        }

           protected override async Task<SomeValues> Process(
            SomeClass2 someClass2,
            SomeClass3 someClass3,
            SomeClass4 someClass4
           )
        {
          ...
          ...
          ...
  
        }
     
    // Below method uses myAppStore
    // Method newly added
        protected override async Task<SomeValues> ProcessWithAuth(
            SomeClass5 someClass5
           )
        {
          ...
          ...
          ...
  
        }

        private AppStoreConfig GetMyAppStoreConfig(){
        ...
        ...
        }


    }

Earlier the test code for above was.

 [TestClass()]
    public class MyClassTests : MyClass 
    {
        

        [TestMethod()]
        public void test1()
        {   
            ...
            ... = this.Process(someClass2,someClass3,someClass4);
            ...
        }
   }

But now it doesn't work as it throws error in GetMyAppStoreConfig(). Currently I don't need to test ProcessWithAuth(), what changes I should make for the test case to work.

I currently cannot create one more constructor and cannot change the protection level in MyClass.cs .

Process() has some code which I want to run in tests and not simply mock.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

病女 2025-02-20 01:13:07

下面的代码对我有用。需要制作getData虚拟并在myAppStore中创建一个无参数构造函数。

    [TestClass()]
    public class MyClassTests 
    {
        private MyClass _myClass;
        private PrivateObject privateObject;

        [TestInitialize()]
        public void init()
        {
            this._myClass = (MyClass)FormatterServices.GetSafeUninitializedObject(typeof(MyClass));
            privateObject = new PrivateObject(this._myClass);
            privateObject.SetField("someClass1;", new SomeClass1());

            var myAppStore  = SetUpMyAppStore();
            
            privateObject.SetField("myAppStore", myAppStore);
        }

        private SetUpMyAppStore()
        {
              var myAppStore = new Mock<MyAppStore>();

              var myData = new MyData();
              myData.val = "1123"
              myAppStore.Setup(x => x.getData("data1")).Returns(Task.FromResult(myData));

              myData = new MyData();
              myData.val = "1124"
              myAppStore.Setup(x => x.getData("data2")).Returns(Task.FromResult(myData));

              return myAppStore.Object;

        }


        

        [TestMethod()]
        public void test1()
        {
            ...
            ... =  (Task<SomeValues>)this.privateObject.Invoke("Process",someClass2,someClass3,someClass4);
            ...
           
        } 


        [TestMethod()]
        public void test2()
        {
            ...
            ... =  (Task<SomeValues>)this.privateObject.Invoke("ProcessWithAuth",someClass5);
            ...
           
        } 
         
    }     ```

Below code worked for me. Needed to make getData virtual and create a no argument constructor in MyAppStore.

    [TestClass()]
    public class MyClassTests 
    {
        private MyClass _myClass;
        private PrivateObject privateObject;

        [TestInitialize()]
        public void init()
        {
            this._myClass = (MyClass)FormatterServices.GetSafeUninitializedObject(typeof(MyClass));
            privateObject = new PrivateObject(this._myClass);
            privateObject.SetField("someClass1;", new SomeClass1());

            var myAppStore  = SetUpMyAppStore();
            
            privateObject.SetField("myAppStore", myAppStore);
        }

        private SetUpMyAppStore()
        {
              var myAppStore = new Mock<MyAppStore>();

              var myData = new MyData();
              myData.val = "1123"
              myAppStore.Setup(x => x.getData("data1")).Returns(Task.FromResult(myData));

              myData = new MyData();
              myData.val = "1124"
              myAppStore.Setup(x => x.getData("data2")).Returns(Task.FromResult(myData));

              return myAppStore.Object;

        }


        

        [TestMethod()]
        public void test1()
        {
            ...
            ... =  (Task<SomeValues>)this.privateObject.Invoke("Process",someClass2,someClass3,someClass4);
            ...
           
        } 


        [TestMethod()]
        public void test2()
        {
            ...
            ... =  (Task<SomeValues>)this.privateObject.Invoke("ProcessWithAuth",someClass5);
            ...
           
        } 
         
    }     ```
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文