urasandesu / Prig

Prig is a lightweight framework for test indirections in .NET Framework.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Getting an error while buliding the project

82Kang opened this issue · comments

I am using Prig ILSpy plugin for generating the Prig Indirection Stub Settings. When i paste the contents into the stub file and try to build the project, it throws the following error.

Error:

The command "cmd /c " "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE..\Tools\VsDevCmd.bat" & %windir%\SysNative\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -NoLogo -NoProfile -File "%URASANDESU_PRIG_PACKAGE_FOLDER%\tools\Invoke-PilotStubber.ps1" -ReferenceFrom "@('%URASANDESU_PRIG_PACKAGE_FOLDER%\lib\Urasandesu.NAnonym.dll','%URASANDESU_PRIG_PACKAGE_FOLDER%\lib\Urasandesu.Prig.Framework.dll')" -AssemblyFrom "C:\Windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll" -TargetFrameworkVersion v4.5.2 -KeyFile "%URASANDESU_PRIG_PACKAGE_FOLDER%\tools\Urasandesu.Prig.snk" -OutputPath "E:\Git\Repository\UnitTests\bin\Debug." -Settings "E:\Git\Repository\UnitTests\mscorlib.v4.0.30319.v4.0.0.0.prig" -BuildTarget BeforeBuild "" exited with code -1.

NOTE:
I have tried the example for DateTime which is given in PRIG Readme and that is working fine. It means the setup is fine.

@urasandesu I am using Visual Studio 2015 and MSTest.

Thank you for the reporting!

It seems that you copy the settings to wrong Stub Settings File.

Which the assembly does the member belong?

You can only write the settings to the Stub Settings File that is generated from the assembly that the member belongs. For example, the settings for System.DateTime.Now can only write to mscorlib.v4.0.30319.v4.0.0.0.prig. MessageBox.Show must be into System.Windows.Forms.v4.0.30319.v4.0.0.0.prig.

Thanks @urasandesu , I got it. Sorry, i missed that part in the Readme. The build is successful and i am able to get the Prig class in my test. But, i have some other doubts.
Eg. I have a class calculator and 2 methods: Add and Multiply

  public class Calculator
  {
    public int Add(int a, int b)
    {
      int c = Multiply(a, b);
      return a + b + c;
    }

    public int Multiply(int a, int b)
    {
      return a * b;
    }
  }

The settings are there in the Stub File as:

    <stubs>
      <!-- 
          PCalculator.AddInt32Int32().Body = 
              args => 
              {   // args[0]: global::TapeManager.Calculator @this, args[1]: global::System.Int32 a, args[2]: global::System.Int32 b
                  throw new NotImplementedException();
              };
      -->
      <add name="AddInt32Int32" alias="AddInt32Int32">
        <RuntimeMethodInfo xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:x="http://www.w3.org/2001/XMLSchema" z:Id="1" z:FactoryType="MemberInfoSerializationHolder" z:Type="System.Reflection.MemberInfoSerializationHolder" z:Assembly="0" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" xmlns="http://schemas.datacontract.org/2004/07/System.Reflection">
          <Name z:Id="2" z:Type="System.String" z:Assembly="0" xmlns="">Add</Name>
          <AssemblyName z:Id="3" z:Type="System.String" z:Assembly="0" xmlns="">TapeManager, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null</AssemblyName>
          <ClassName z:Id="4" z:Type="System.String" z:Assembly="0" xmlns="">TapeManager.Calculator</ClassName>
          <Signature z:Id="5" z:Type="System.String" z:Assembly="0" xmlns="">Int32 Add(Int32, Int32)</Signature>
          <Signature2 z:Id="6" z:Type="System.String" z:Assembly="0" xmlns="">System.Int32 Add(System.Int32, System.Int32)</Signature2>
          <MemberType z:Id="7" z:Type="System.Int32" z:Assembly="0" xmlns="">8</MemberType>
          <GenericArguments i:nil="true" xmlns="" />
        </RuntimeMethodInfo>
      </add>

      <!-- 
          PCalculator.MultiplyInt32Int32().Body = 
              args => 
              {   // args[0]: global::TapeManager.Calculator @this, args[1]: global::System.Int32 a, args[2]: global::System.Int32 b
                  throw new NotImplementedException();
              };
      -->
      <add name="MultiplyInt32Int32" alias="MultiplyInt32Int32">
        <RuntimeMethodInfo xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:x="http://www.w3.org/2001/XMLSchema" z:Id="1" z:FactoryType="MemberInfoSerializationHolder" z:Type="System.Reflection.MemberInfoSerializationHolder" z:Assembly="0" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" xmlns="http://schemas.datacontract.org/2004/07/System.Reflection">
          <Name z:Id="2" z:Type="System.String" z:Assembly="0" xmlns="">Multiply</Name>
          <AssemblyName z:Id="3" z:Type="System.String" z:Assembly="0" xmlns="">TapeManager, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null</AssemblyName>
          <ClassName z:Id="4" z:Type="System.String" z:Assembly="0" xmlns="">TapeManager.Calculator</ClassName>
          <Signature z:Id="5" z:Type="System.String" z:Assembly="0" xmlns="">Int32 Multiply(Int32, Int32)</Signature>
          <Signature2 z:Id="6" z:Type="System.String" z:Assembly="0" xmlns="">System.Int32 Multiply(System.Int32, System.Int32)</Signature2>
          <MemberType z:Id="7" z:Type="System.Int32" z:Assembly="0" xmlns="">8</MemberType>
          <GenericArguments i:nil="true" xmlns="" />
        </RuntimeMethodInfo>
      </add>

      <!-- 
          PCalculator.Constructor().Body = 
              args => 
              {   // args[0]: global::TapeManager.Calculator @this
                  throw new NotImplementedException();
              };
      -->
      <add name="Constructor" alias="Constructor">
        <RuntimeConstructorInfo xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:x="http://www.w3.org/2001/XMLSchema" z:Id="1" z:FactoryType="MemberInfoSerializationHolder" z:Type="System.Reflection.MemberInfoSerializationHolder" z:Assembly="0" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" xmlns="http://schemas.datacontract.org/2004/07/System.Reflection">
          <Name z:Id="2" z:Type="System.String" z:Assembly="0" xmlns="">.ctor</Name>
          <AssemblyName z:Id="3" z:Type="System.String" z:Assembly="0" xmlns="">TapeManager, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null</AssemblyName>
          <ClassName z:Id="4" z:Type="System.String" z:Assembly="0" xmlns="">TapeManager.Calculator</ClassName>
          <Signature z:Id="5" z:Type="System.String" z:Assembly="0" xmlns="">Void .ctor()</Signature>
          <Signature2 z:Id="6" z:Type="System.String" z:Assembly="0" xmlns="">.ctor()</Signature2>
          <MemberType z:Id="7" z:Type="System.Int32" z:Assembly="0" xmlns="">1</MemberType>
          <GenericArguments i:nil="true" xmlns="" />
        </RuntimeConstructorInfo>
      </add>


    </stubs>
    

I am trying to write test case for Addition using MSTest:


1.   [TestClass()]
2.   public class CalculatorTests
3.   {
4.     [TestMethod()]
5.     public void AddTest()
6.     {
7.       using (new IndirectionsContext())
8.       {
9.         int a = 10, b = 3, c = 4;
10.         PCalculator.MultiplyInt32Int32().Body = ???????????
11.         int actual = new Calculator().Add(a, b);
12.       }
13.         Assert.Fail();
14.     }
15.   }

In line 10, i am getting that we are trying to give the definition of the method at run-time. In the Stub Setting file, the MultiplyInt32Int32() takes 3 args. How to pass those args. I have tried many ways but it is giving an error that cannot implicit convert to Work.
Please tell me how to use this and one more thing, if i do not want to write a body of the method and just want to return something, suppose i want Multiply(a,b) should return c,something like,

PCalculator.MultiplyInt32Int32().Return = 10;
How to make it work ?

Thanks in advance

It seems that you create the stub against a non-public member (see our wiki section Indirection Delegate).
I guess that you copied the setting from the old assembly that is before you make the class public. Try to refresh assembly and copy the setting again.