Как Вы блокируете IQueryable <T>.Where (Func <T, bool>) с Насмешками Носорога?

Нет, невозможно PIVOT обойтись без агрегатной функции, но вы можете сделать агрегатную функцию произвольной, обеспечив только одну исходную строку на группу. Из вашего вопроса не сразу понятно, в чем заключается ваша логика:

Например, у вас есть два значения для времени 12 (KA108112 и KA106360) и 3 строки для времени 13 (TN04F6726, TN28C3709, TN52C4788), так что есть несколько разных способов объединить эти два.

Вы можете вернуть декартово произведение:

12          13
----------------------
KA108112    TN04F6726
KA106360    TN04F6726
KA108112    TN28C3709
KA106360    TN28C3709
KA108112    TN52C4788
KA106360    TN52C4788

Или вы можете вернуть каждый результат один раз, например

12          13
----------------------
KA106360    TN04F6726
KA108112    TN28C3709
NULL        TN52C4788

Но вам также необходимо предоставить дополнительную логику, то есть, почему KA106360 будет соответствовать TN04F6726, а не любому из двух других значений (в приведенном выше примере у меня есть ordererd Trailer_RegNo в алфавитном порядке каждый раз, но может быть любое количество способов сделать это.

Исходя из вашего комментария, кажется, что вы хотите произвольно спарить значения, поэтому, чтобы убедиться, что каждое значение представлено, вам нужно сделать каждую строку уникальной , что вы можете сделать, используя ROW_NUMBER(), например

DECLARE @T TABLE (Time INT, Trailer_RegNo VARCHAR(20));
INSERT @T (Time, Trailer_RegNo)
VALUES (12, 'KA108112'), (12, 'KA106360'), (13, 'TN04F6726'), (13, 'TN28C3709'), (13, 'TN52C4788');

SELECT  Trailer_RegNo, 
        Time,
        RowNumber = ROW_NUMBER() OVER(PARTITION BY [Time] ORDER BY Trailer_RegNo) 
FROM    @T;

, что дает:

Trailer_RegNo   Time    RowNumber
----------------------------------
KA106360        12      1
KA108112        12      2
TN04F6726       13      1
TN28C3709       13      2
TN52C4788       13      3

Теперь у вас есть способ сопряжения ваших предметов (например, KA106360 и TN04F6726, KA108112 и amp ; TN28C3709 и т. Д.) Чтобы изменить порядок группировки элементов, вам просто нужно изменить предложение ORDER BY в функции ROW_NUMBER().

Таким образом, ваш последний запрос может выглядеть примерно так:

[114 ]
5
задан Mark Rogers 27 April 2009 в 01:49
поделиться

3 ответа

I initially wanted to mock out calls like 'IQueryable.Where(Func)' too but I think it is testing at the wrong level. Instead in my tests I just mocked out IQueryable and then check the result:

// Setup a dummy list that will be filtered, queried, etc
var actionList = new List<ActionType>()
{
    new ActionType() { Name = "debug" },
    new ActionType() { Name = "other" }
};
_repository.Expect(x => x.Query<ActionType>()).Return(actionList);

var result = _service.GetAvailableActions().ToList();

// Check the logic of GetAvailableActions returns the correct subset 
// of actionList, etc:
Assert.That(result.Length, Is.EqualTo(1));
Assert.That(result[0], Is.EqualTo(actionList[0]);

_repository.VerifyAllExpectations();
5
ответ дан 18 December 2019 в 09:53
поделиться

Не используя насмешки Rhino, вы можете создать список и затем вызвать .AsQueryable () для него. например,

var actionTypeList = new List<ActionType>() {
    new ActionType {},  //put your fake data here
    new ActionType {}
};

var actionTypeRepo = actionTypeList.AsQueryable();

Это, по крайней мере, даст вам поддельное хранилище, но не позволит вам проверить, были ли вызваны методы.

6
ответ дан 18 December 2019 в 09:53
поделиться

Where is an extension method, this is not a method implemented by the interface IQueriable. Look at the members of IQueriable: http://msdn.microsoft.com/en-us/library/system.linq.iqueryable_members.aspx

An extension method is static and can't be mocked. IMO, there is no need to mock Where, because it's part of the language. You should only mock the repository.

Edit, Example:

[TestFixture]
public class ServiceClassTester
{
    private ServiceClass _service;
    private IRepository _repository;
    private IQueryable<ActionType> _actionQuery;

    [SetUp]
    public void SetUp()
    {
        _service = new ServiceClass(_repository);

        // set up the actions. There is probably a more elegant way than this.
        _actionQuery = (new List<ActionType>() { ActionA, ActionB }).AsQueryable();

        // setup the repository
        _repository = MockRepository.GenerateMock<IRepository>();
        _repository.Stub(x => x.Query<ActionType>()).Return(_actionQuery);
    }

    [Test]
    public void heres_a_test()
    {
        // act
        var actions = _service.GetAvailableActions();

        // assert
        Assert.AreEqual(1, actions.Count());
        // more asserts on he result of the tested method
    }

}

Note: you don't need to expect the call, because your method depends on the return value of the mock. If it wouldn't call it, it would fail on the asserts. This makes your test easier to maintain.

6
ответ дан 18 December 2019 в 09:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: