Vra

Ek het 'n paar MSBuild persoonlike take wat goed werk en is gebruik in ons CruiseControl.NET bou proses geskryf.

Ek verander een, en wil eenheid toets dit deur te bel metode die Taak se Voer ().

As dit ontmoetings 'n lyn met

Log.LogMessage("some message here");

Dit gooi 'n InvalidOperationException:

Taak probeer om aan te meld voordat dit geïnisialiseer. Boodskap was ...

Enige voorstelle? (In die verlede het ek meestal-eenheid getoets Interne statiese metodes op my persoonlike take om sulke probleme te vermy.)

Was dit nuttig?

Oplossing

Jy moet die eiendom .BuildEngine van die persoonlike taak wat jy doen 'n beroep stel.

Jy kan dit stel om dieselfde BuildEngine jou huidige taak gebruik om die uitset moeiteloos te sluit.

Task myCustomTask = new CustomTask();
myCustomTask.BuildEngine = this.BuildEngine;
myCustomTask.Execute();

Ander wenke

Ek het gevind dat die log byvoorbeeld nie werk nie, tensy die taak is wat binne msbuild, so ek gewoonlik draai my oproepe na log, dan gaan die waarde van BuildEngine te bepaal tussen as ek loop in msbuild. Soos hieronder.

Tim

private void LogFormat(string message, params object[] args)
{
    if (this.BuildEngine != null)
    {
        this.Log.LogMessage(message, args);
    }
    else
    {
        Console.WriteLine(message, args);
    }
}

@Kiff kommentaar op mock / stomp IBuildEngine is 'n goeie idee. Hier is my FakeBuildEngine. C # en VB.NET voorbeelde verskaf.

VB.NET

Imports System
Imports System.Collections.Generic
Imports Microsoft.Build.Framework

Public Class FakeBuildEngine
    Implements IBuildEngine

    // It's just a test helper so public fields is fine.
    Public LogErrorEvents As New List(Of BuildErrorEventArgs)
    Public LogMessageEvents As New List(Of BuildMessageEventArgs)
    Public LogCustomEvents As New List(Of CustomBuildEventArgs)
    Public LogWarningEvents As New List(Of BuildWarningEventArgs)

    Public Function BuildProjectFile(
        projectFileName As String, 
        targetNames() As String, 
        globalProperties As System.Collections.IDictionary, 
        targetOutputs As System.Collections.IDictionary) As Boolean
        Implements IBuildEngine.BuildProjectFile

        Throw New NotImplementedException

    End Function

    Public ReadOnly Property ColumnNumberOfTaskNode As Integer 
        Implements IBuildEngine.ColumnNumberOfTaskNode
        Get
            Return 0
        End Get
    End Property

    Public ReadOnly Property ContinueOnError As Boolean
        Implements IBuildEngine.ContinueOnError
        Get
            Throw New NotImplementedException
        End Get
    End Property

    Public ReadOnly Property LineNumberOfTaskNode As Integer
        Implements IBuildEngine.LineNumberOfTaskNode
        Get
            Return 0
        End Get
    End Property

    Public Sub LogCustomEvent(e As CustomBuildEventArgs)
        Implements IBuildEngine.LogCustomEvent
        LogCustomEvents.Add(e)
    End Sub

    Public Sub LogErrorEvent(e As BuildErrorEventArgs)
        Implements IBuildEngine.LogErrorEvent
        LogErrorEvents.Add(e)
    End Sub

    Public Sub LogMessageEvent(e As BuildMessageEventArgs)
        Implements IBuildEngine.LogMessageEvent
        LogMessageEvents.Add(e)
    End Sub

    Public Sub LogWarningEvent(e As BuildWarningEventArgs)
        Implements IBuildEngine.LogWarningEvent
        LogWarningEvents.Add(e)
    End Sub

    Public ReadOnly Property ProjectFileOfTaskNode As String
        Implements IBuildEngine.ProjectFileOfTaskNode
        Get
            Return "fake ProjectFileOfTaskNode"
        End Get
    End Property

End Class

C #

using System;
using System.Collections.Generic;
using Microsoft.Build.Framework;

public class FakeBuildEngine : IBuildEngine
{

    // It's just a test helper so public fields is fine.
    public List<BuildErrorEventArgs> LogErrorEvents = new List<BuildErrorEventArgs>();

    public List<BuildMessageEventArgs> LogMessageEvents = 
        new List<BuildMessageEventArgs>();

    public List<CustomBuildEventArgs> LogCustomEvents = 
        new List<CustomBuildEventArgs>();

    public List<BuildWarningEventArgs> LogWarningEvents =
        new List<BuildWarningEventArgs>();

    public bool BuildProjectFile(
        string projectFileName, string[] targetNames, 
        System.Collections.IDictionary globalProperties, 
        System.Collections.IDictionary targetOutputs)
    {
        throw new NotImplementedException();
    }

    public int ColumnNumberOfTaskNode
    {
        get { return 0; }
    }

    public bool ContinueOnError
    {
        get
        {
            throw new NotImplementedException();
        }
    }

    public int LineNumberOfTaskNode
    {
        get { return 0; }
    }

    public void LogCustomEvent(CustomBuildEventArgs e)
    {
        LogCustomEvents.Add(e);
    }

    public void LogErrorEvent(BuildErrorEventArgs e)
    {
        LogErrorEvents.Add(e);
    }

    public void LogMessageEvent(BuildMessageEventArgs e)
    {
        LogMessageEvents.Add(e);
    }

    public void LogWarningEvent(BuildWarningEventArgs e)
    {
        LogWarningEvents.Add(e);
    }

    public string ProjectFileOfTaskNode
    {
        get { return "fake ProjectFileOfTaskNode"; }
    }

}

As jy die koppelvlak ITask jy sal hê om jouself te inisialiseer die Meld klas geïmplementeer.

Andersins moet jy net besit van Taak in Microsoft.Build.Utilities.dll Wat implemente ITask en doen 'n groot deel van die been vir jou werk.

Hier is die verwysing bladsy vir die bou van 'n persoonlike taak, dit verduidelik nogal 'n baie van dit.

bou van 'n persoonlike MSBuild taak verwysing

Ook die moeite werd 'n blik is

Hoe om 'n persoonlike MSBuild taak ontfout

Ander dan dat jy kan plaas die MSBuild XML wat jy gebruik vir 'n beroep jou persoonlike taak. Die kode self sou natuurlik wees om die mees hulp: -)

Ek het dieselfde probleem. Ek opgelos dit deur stubbing die bou enjin. Soos so (AppSettings is die MsBuild Taak Naam):

using Microsoft.Build.Framework;
using NUnit.Framework;
using Rhino.Mocks;

namespace NameSpace
{
    [TestFixture]
    public class Tests
    {
        [Test]
        public void Test()
        {
            MockRepository mock = new MockRepository();
            IBuildEngine engine = mock.Stub<IBuildEngine>();

            var appSettings = new AppSettings();
            appSettings.BuildEngine = engine;
            appSettings.Execute();
        }
    }
}

In die gemeente System.Web in namespace System.Web.Compilation is 'n klas MockEngine wat IBuildEngine interface implemente op 'n manier wat Tim Murphy beskryf.

Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top